Bug 19903 – postblit called for uninitialised elements of unions
Status
RESOLVED
Resolution
DUPLICATE
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-05-26T17:14:34Z
Last change time
2019-05-28T12:08:22Z
Assigned to
No Owner
Creator
Manu
Comments
Comment #0 by turkeyman — 2019-05-26T17:14:34Z
import std.stdio;
struct T
{
this(this) { writeln("dun postblit\n"); }
float f = 0;
}
struct S
{
union {
int x = 0;
T y = void; // <- void initialised
}
int which = 0;
}
S a;
S b = a; // <- assignment calls postblit
This assignment calls the T postblit, which is a `void` initialised member of a union.
This is just a hard crash waiting to happen!
This pattern should be supplanted with copy-ctors.
I suggest a reasonable resolution is:
1. no such implicit non-trivial assignment is attempted inside a union
2. if a union contains an element with a non-trivial copy, then a copy-ctor must be defined otherwise user receives a compile error informing them such.
2a. perhaps rather than emitting a compile error, it might be better to emit an automatic @disable copy constructor for that object.
I think it's the case that any union with elaborate copy semantics can only be correctly composed by the author of the union.
Comment #1 by turkeyman — 2019-05-26T20:40:07Z
Oh my, I just noticed that the DESTRUCTOR is also called for each element in the union!
That's completely wrong, since only one item in the union may be valid at a time.
Comment #2 by turkeyman — 2019-05-27T21:37:09Z
Raising this to blocker. unions are completely useless in D with this issue in place, and I can't continue.
Comment #3 by razvan.nitu1305 — 2019-05-28T11:17:57Z
(In reply to Manu from comment #0)
> This assignment calls the T postblit, which is a `void` initialised member
> of a union.
> This is just a hard crash waiting to happen!
>
> This pattern should be supplanted with copy-ctors.
> I suggest a reasonable resolution is:
> 1. no such implicit non-trivial assignment is attempted inside a union
> 2. if a union contains an element with a non-trivial copy, then a
> copy-ctor must be defined otherwise user receives a compile error informing
> them such.
> 2a. perhaps rather than emitting a compile error, it might be better to
> emit an automatic @disable copy constructor for that object.
>
> I think it's the case that any union with elaborate copy semantics can only
> be correctly composed by the author of the union.
Spec:
"Unions may have fields that have postblits. However, a union itself never has a postblit. Copying a union does not result in postblit calls for any fields. If those calls are desired, they must be inserted explicitly by the programmer."
It seems that it has a problem with anonymous unions. Slightly changing your program results in corect behavior:
import std.stdio;
struct T
{
this(this) { writeln("dun postblit\n"); }
float f = 0;
}
struct S
{
union U { // the union is named now
int x = 0;
T y = void; // <- void initialised
}
U u; // and we have a field
int which = 0;
}
S a;
S b = a; // <- assignment calls postblit
Comment #4 by simen.kjaras — 2019-05-28T12:08:22Z
*** This issue has been marked as a duplicate of issue 19122 ***