UPDATE: I do appreciate \"don\'t want that, want this instead\" suggestions. They are useful, especially when provided in context of the motivating scenari
struct myPOD {
int data1;
// ...
};
struct myPOD_extended1 : myPOD {
int helper() { (*(myPOD*)this)->data1 = 6; }; // type myPOD referenced here
};
struct myPOD_extended2 : myPOD {
int helper() { data1 = 7; }; // no syntactic ref to myPOD
};
struct myPOD_extended3 : myPOD {
int helper() { (*(myPOD*)this)->data1 = 8; }; // type myPOD referenced here
};
void doit(myPOD *it)
{
((myPOD_extended1*)it)->helper();
// ((myPOD_extended2*)it)->helper(); // uncomment -> program/compile undefined
((myPOD_extended3*)it)->helper();
}
int main(int,char**)
{
myPOD a; a.data1=5;
doit(&a);
std::cout<< a.data1 << '\n';
return 0;
}
I believe this is guaranteed to work in all conforming C++ compilers and must print 8. Uncomment the marked line and all bets are off.
An optimizer might prune searches for valid aliased references by checking the list of syntactic types actually referenced in a function against the list (in 3.10p10) of syntactic types of references it's required to produce correct results for -- and when an actual ("dynamic") object type is known, that list doesn't include access through a reference to any derived type. So the explicit (and valid) downcasts of this to myPOD* in the helper()s puts myPOD on the list of types syntactically referenced there, and the optimizer has to treat the resulting references as potential legal references to (other names for, aliases of) the object a.