Sergei Organov writes:
 > Ian Lance Taylor <[EMAIL PROTECTED]> writes:
 > > Sergei Organov <[EMAIL PROTECTED]> writes:
 > >
 > 
 > >> $ cat alias.c
 > >> typedef struct { int i; } S;
 > >> 
 > >> int i;
 > >> int foo()
 > >> {
 > >>   S const sc = { 10 };
 > >>   i = 20;
 > >>   // Accessing object 'i' of type 'int' through 'S' containing 'int'
 > >>   // field.  Should be OK from C99 standard POV?
 > >>   *(S*)&i = sc;
 > >
 > > C99 says that you can access an object via "an aggregate or union type
 > > that includes one of the aforementioned [basically, compatible] types
 > > among its members (including, recursively, a member of a subaggregate
 > > or contained union)" (section 6.5, paragraph 7).  So on that basis
 > > this looks OK to me.
 > 
 > Yes, it looked OK due to that rule to me too, until I just came up with
 > the following example in which either I've finally violated some rule,
 > or GCC miscompiles the code:
 > 
 > $cat alias3.c
 > typedef struct {
 >   int i;
 >   float f;
 > } H0;
 > 
 > typedef struct {
 >   float f;
 >   int i;
 > } H1;
 > 
 > H1 h1 = { 0, 10 };
 > 
 > int float_as_int() __attribute__((noinline));
 > int float_as_int()
 > {
 >   h1.f = 1;
 >   H0 h0 = *(H0*)&h1.f; // Should be OK? No, it is not?!

I don't think this is OK.  Per C99, you can cast to the element type
from the struct or vice versa, but you can't cast from one struct type
to another via the first element.  If this were possible, every struct
type that started with an int would be in a single alias set.

Andrew.

Reply via email to