[PATCH]: Fix PR tree-optimization/21407

Zack Weinberg zack@codesourcery.com
Tue May 10 18:26:00 GMT 2005


Daniel Berlin <dberlin@dberlin.org> writes:

>> Construct 2:
>> 
>>  struct Base
>>  {
>>    int a;
>>    int b;
>>  };
>> 
>>  struct Derived
>>  {
>>    int c;
>>    int d;
>>    struct Base b;
>>    int e;
>>    int f;
>>  };
>> 
>>  void foo(struct Base *b)
>>  {
>>    struct Derived *d = 
>>      (struct Derived *) ((char *)b) - offsetof(struct Derived, b);
>> 
>>    d->c = 23;
>>  }
>> 
>>  void bar(struct Derived *d)
>>  {
>>    foo (&d->b);
>>  }
>
>> However, it is my opinion that construct 2 *is* allowed by the
>> standard.  Obviously nothing fishy is happening up till the first
>> statement of foo.  foo begins by converting b to a char*, which is an
>> escape hatch - everything aliases an array of char (6.5p7), and the
>> pointer is guaranteed to point to the first byte of Derived.b
>> (6.3.2.3p7).
>
> If i change "struct Base b" to "int b", and have foo take an "int *b" is
> it still legal?
> After all, you are still casting to a char * what appears to be a
> pointer guaranteed to point to the beginning of Derived, by the same
> logic.

I don't see anything in the standard that distinguishes the two cases;
I suspect real-world uses of this construct will only use pointers to
member structures, not member scalars, but applying that heuristic
still potentially puts us in the land of breaking strictly conforming
code.  No, I'm not happy about this.

zw



More information about the Gcc-patches mailing list