Andrew Haley <[EMAIL PROTECTED]> writes:

> 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.

There is no word "casting" in the definition of the aliasing rules in
C99. It talks about accessing of object through an lvalue of compatible
type. In this example I access stored value of object "h1.f" of type
"float" through an lvalue of type "H0" that is an aggregate type that
includes "float" (a type compatible with the effective type of the
object) among its members. That IMHO should be OK from C99
aliasing rules POV.

> If this were possible, every struct type that started with an int
> would be in a single alias set.

How else should I interpret these C99 wordings (re-citing again):

  An object shall have its stored value accessed only by an lvalue
  expression that has one of the following types: {footnote 73}

     - a type compatible with the effective type of the object,
     [...]
     - an aggregate or union type that includes one of the aforementioned
       types among its members (including, recursively, a member of a
       subaggregate or contained union)


-- Sergei.

Reply via email to