Thread overview
[Issue 16104] Unions should allow fields with destructors, postblits, and invariants
May 31, 2016
Walter Bright
May 31, 2016
Walter Bright
Jul 02, 2017
Vladimir Panteleev
May 31, 2016
https://issues.dlang.org/show_bug.cgi?id=16104

Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com

--- Comment #1 from Walter Bright <bugzilla@digitalmars.com> ---
In C++:

  struct S {  ~S(); };
  union U  { S s; };

g++ -c foo.cpp
foo.cpp:2:14: error: member 'S U::s' with destructor not allowed in union
 union U  { S s; };
              ^
foo.cpp:2:14: note: unrestricted unions only available with -std=c++11 or
-std=gnu++11


What was C++11's rationale?

--
May 31, 2016
https://issues.dlang.org/show_bug.cgi?id=16104

--- Comment #2 from Walter Bright <bugzilla@digitalmars.com> ---
Consider:

  struct S { ~this(); }
  struct T { S s; }

The compiler will automatically create a destructor for T that will call the destructor for s, or will add code to do that to the destructor for T.

  union U { S1 a; S2 b; }
  U u;

What happens to RIAA with this?

--
May 31, 2016
https://issues.dlang.org/show_bug.cgi?id=16104

--- Comment #3 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Walter Bright from comment #1)
> In C++:
> 
>   struct S {  ~S(); };
>   union U  { S s; };
> 
> g++ -c foo.cpp
> foo.cpp:2:14: error: member 'S U::s' with destructor not allowed in union
>  union U  { S s; };
>               ^
> foo.cpp:2:14: note: unrestricted unions only available with -std=c++11 or
> -std=gnu++11
> 
> 
> What was C++11's rationale?

Forgot to mention Lois Goldthwaite's work on this: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf. It's a great fix of C++ without which implementing things like variant types portably was next to impossible.

--
May 31, 2016
https://issues.dlang.org/show_bug.cgi?id=16104

--- Comment #4 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Walter Bright from comment #2)
> Consider:
> 
>   struct S { ~this(); }
>   struct T { S s; }
> 
> The compiler will automatically create a destructor for T that will call the destructor for s, or will add code to do that to the destructor for T.
> 
>   union U { S1 a; S2 b; }
>   U u;
> 
> What happens to RIAA with this?

You mean RAII? There's none of it in unions. As I said, putting data in unions automatically disables all automatic calls. Putting stuff in unions is purely layout definition and manipulation. All calls must be inserted by the code using the union (which is usually encapsulated in a struct wrapping the union and providing discrimination).

--
July 02, 2017
https://issues.dlang.org/show_bug.cgi?id=16104

Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |dlang-bugzilla@thecybershad
                   |                            |ow.net
           See Also|                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=2665,
                   |                            |https://issues.dlang.org/sh
                   |                            |ow_bug.cgi?id=4144
         Resolution|---                         |WORKSFORME

--- Comment #5 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
I believe this was fixed in https://github.com/dlang/dmd/pull/5830.

BTW, the example in the description has a non-trivial history:

.. before 2.063 : test.d(24): Error: mutable method test.A1.opAssign is not callable using a immutable object

Fixed  by: https://github.com/dlang/dmd/pull/2665 (issue 9665)

2.064 ... 2.066 : works

Broken by: https://github.com/dlang/dmd/pull/4144 (issue 4421)

2.067 ... 2.071 : test.d(12): Error: struct test.B destructors, postblits and invariants are not allowed in overlapping fields a1 and a2

Fixed  by: https://github.com/dlang/dmd/pull/5830

2.072 ... now   : works

--