https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
--- Comment #16 from rguenther at suse dot de <rguenther at suse dot de> --- On Mon, 25 Jun 2018, glisse at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259 > > --- Comment #15 from Marc Glisse <glisse at gcc dot gnu.org> --- > (In reply to Martin Sebor from comment #14) > > > You say that > > > > > > struct { int a; int b; } s, s2; > > > memcpy (&s2.a, &s.a, sizeof (s)); > > > > > > is invalid, aka not copying the whole structure since you pass in a > > > pointer to s2.a rather than s2? > > > > Yes. > > Let's give the struct a name and introduce some casts > > typedef struct { int a; int b; } S; > S s, s2; > memcpy ((S*)&s2.a, (S*)&s.a, sizeof(s)); > > The standard makes it valid to convert &s.a to S* and makes it equivalent to > &s. Because of the call to memcpy, it gets converted to void* afterwards. So > you are saying that (void*)&s.a is not the same as (void*)(S*)&s.a (note that > no arithmetic is involved at this point). This looks like it is going to cause > trouble... Similarly for (char *) conversions as performed by str* calls, 6.3.2.3/7 applies which says "When a pointer to _an object_ is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object." Now, "object" is defined as "region of data storage in the execution environment, the contents of which can represent values" and 6.5.3.2 suggests that & of an lvalue points to the "object" designated by that lvalue. That again makes (char *)&*(S *)&s2.a not the same as (char *)&s2.a semantically. As a general comment I find it disturbing that the user is required to write (char *)&s2 + offsetof(S, a) instead of plain &s2.a (whatever offset a actually has, thus considering my second example as well) when calling str* or mem* routines. At least it re-inforces my doubt on any address-computation to component-ref folding we still have (plenty!). That said, as of QOI I seriously doubt taking advantage of the above for optimization purposes is a good idea given there isn't even a flag like -fwrapv or -fno-strict-aliasing to disable it!