This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH]: Fix PR tree-optimization/21407


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]