+Cc gcc-list. Does any gcc developer have any comments?
On Mon, Sep 25, 2017 at 01:41:55PM -0700, Myriachan wrote: > This question that "supercat" posted on Stack Overflow ran into an > interesting problem: > > https://stackoverflow.com/questions/46205744/is-this-use-of-unions-strictly-conforming/ > > A copy of the code involved is as follows: > > struct s1 {unsigned short x;}; > struct s2 {unsigned short x;}; > union s1s2 { struct s1 v1; struct s2 v2; }; > > static int read_s1x(struct s1 *p) { return p->x; } > static void write_s2x(struct s2 *p, int v) { p->x=v;} > > int test(union s1s2 *p1, union s1s2 *p2, union s1s2 *p3) > { > if (read_s1x(&p1->v1)) > { > unsigned short temp; > temp = p3->v1.x; > p3->v2.x = temp; > write_s2x(&p2->v2,1234); > temp = p3->v2.x; > p3->v1.x = temp; > } > return read_s1x(&p1->v1); > } > int test2(int x) > { > union s1s2 q[2]; > q->v1.x = 4321; > return test(q,q+x,q+x); > } > #include <stdio.h> > int main(void) > { > printf("%d\n",test2(0)); > } > > > Both GCC and Clang in -fstrict-aliasing mode with optimizations are acting > as if they ran into undefined behavior, and return 4321 instead of the > expected 1234. This happens in both C and C++ mode. Intel C++ and Visual > C++ return the expected 1234. All four compilers hardwire the result as a > constant parameter to printf rather than call test2 or modify memory at > runtime. > > From my reading of the C++ Standard, particularly [class.union]/5, > assignment expressions through a union member access changes the active > member of the union (if the union member has a trivial default constructor, > which it does here, being C code). Taking the address of p2->v2 and p1->v1 > ought to be legal because those are the active members of the union at the > time their pointers are taken. > > Is this a well-defined program, or is there subtle undefined behavior > happening here? > > Melissa > > -- > > --- > You received this message because you are subscribed to the Google Groups > "ISO C++ Standard - Discussion" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to std-discussion+unsubscr...@isocpp.org. > To post to this group, send email to std-discuss...@isocpp.org. > Visit this group at > https://groups.google.com/a/isocpp.org/group/std-discussion/.