On Tue, Mar 10, 2015 at 10:11 AM, Robbert Krebbers <mailingli...@robbertkrebbers.nl> wrote: > Dear Richard, > > On 03/10/2015 09:51 AM, Richard Biener wrote: >> >> struct X { int i; int j; }; >> >> int foo (struct X *p, struct X *q) >> { >> q->j = 1; >> p->i = 0; >> return q->j; >> } >> >> will optimize to return 1. If *p and *q were allowed to overlap >> (&p->i == &q->j) >> this would invoke undefined behavior. > > Thanks for the example! > > I guess you are considering the case where q.j and p.i overlap. For example: > > int main() { > assert(sizeof(struct X) == 2 * sizeof(int)); > unsigned char *p = malloc(3 * sizeof(int)); > return foo ((struct X*)(p + sizeof(int)), (struct X*)p); > } > > In a naive memory model, one would indeed expect this program to return 0 > instead of 1 (which GCC does). > > However, this program already invokes undefined behavior due to C11's notion > of effective types, namely 6.5p6 and 6.5p7. > > So, let me rephrase my question. Is anyone aware of situations in which GCC > uses 6.5.16.1p3 as a license to perform certain optimizations where > effective types alone do not suffice.
No, both are quite tied together (well, you might run into interpretation issues with respect to "effective type" and the overlap constraint might save you). Richard. > Robbert