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.

Reply via email to