Consider this code example:
#include <stdio.h>
typedef struct A A;
struct A {
int x;
int y;
};
typedef struct B B;
struct B {
int x;
int y;
int z;
};
int main()
{
B b = {1,2,3};
A *ap = (A*)&b;
*ap = (A){100,200}; //a clear http://port70.net/~nsz/c/c11/n1570.html#6.5p7 violation
ap->x = 10; ap->y = 20; //lvalues of types int and int at the right addrresses, ergo correct ?
printf("%d %d %d\n", b.x, b.y, b.z);
}
I used to think that something like casting B* to A* and using A* to manipulate the B* object was a strict aliasing violation. But then I realized the standard really only requires that:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types: 1) a type compatible with the effective type of the object, (...)
and expressions such as ap->x
do have the correct type and address, and the type of ap
shouldn't really matter there (or does it?). This would, in my mind, imply that this type of overlay inheritance is correct as long as the substructure isn't manipulated as a whole.
Is this interpretation flawed or ostensibly at odds with what the authors of the standard intended?