https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
--- Comment #69 from rguenther at suse dot de <rguenther at suse dot de> --- On March 27, 2017 8:11:10 PM GMT+02:00, "matz at gcc dot gnu.org" <gcc-bugzi...@gcc.gnu.org> wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671 > >--- Comment #68 from Michael Matz <matz at gcc dot gnu.org> --- >(In reply to Jonathan Wakely from comment #65) >> It accesses b, but it doesn't access the object stored in b's char[N] >member >> via placement new. > >Okay, let's go with this. So the copying of the union is then defined >(as a memcpy equivalent). Then there's still the question if the >following >sequences are valid: > >// assume T1 and T2 are some types and new is trivial placement new >union U {T1 a; char b[sizeof T2];} x,y; >new (x.b) T2(); // 1 >y = x; // 2 >T2 t; >memcpy(&t, y.b, sizeof T2); // 3 >t; // 4 >y.a; // 5 > >We have said that (2) is valid, obviously (3) in isolation is valid as >well, >but it influences the validity of (4). (5) is invalid as it's not the >active member of the union y (which is instead b). > >(4) is valid if y.b contained a T2, which is only the case if (2) >transferred >the dynamic type from x.b _and_ (1) was valid to start with and >dynamically >typed x.b to be of type T2. > >So, it all boils down to if (1) is valid and types x.b to T2, even >though it >has a different declared type. For C we say it's not, because char[] >is >asymmetric: you can access all types via a char*, but you can't change >the >dynamic type of a declared char array to contain arbitrary other things >(well, >the ME memory model does cater for this and makes it valid, even though >it's >invalid in C). > >I guess you're arguing that (1) is valid in C++ and that then due to >3.9/3 >and 12.8/29 also (2) and (4) are. I guess it can be defined to be so, >but >I wonder what the type of 'x' is after (1)? It can't be T2, because >clearly >x.b is valid even if T2 doesn't contain a member 'b'. So it must stay >a union, >but in order to transfer the type T2 in (2) it must also contain T2, so >is it >the type 'union {T1 a; char b[sizeof T2]; T2 <unnamed>;}' then >(conceptually)? >Messy :) As I noted elsewhere union members in C++ seem to be pure convenience and a union contains implicit members of all types (well, somehow factor in alignment). Of course Jason argues char[] is special and introduces this but I can't find text anywhere to support that or require char[] and not, say int[]. Richard.