built-in types inside of a union

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Jul 13 07:22:29 PDT 2016


On 07/13/2016 07:01 AM, Adam D. Ruppe wrote:
 > On Wednesday, 13 July 2016 at 12:28:57 UTC, zodd wrote:
 >> This code works as I expected but I'm unsure that it's correct.
 >
 > Yes, your code is legal.
 >
 > What isn't legal is using some type that isn't there at runtime, like
 >
 > union A {
 >     int[] a;
 >     char[] b;
 > }
 >
 > A u;
 >
 > u.a = [1,2];
 >
 > u.b.length
 >
 >
 > The compiler will let you do it, but being a union, it will show length
 > == 1 because it was set to an int[], but that's not really correct for a
 > char[].
 >
 >
 > But the way you did it, initializing to the proper type before accessing
 > it, is allowed.

Although, in some cases even that assignment operation can do the wrong 
thing. In general, the left-hand side of the assignment does not hold 
the invariants of that user-defined type:

import std.stdio;

struct S {
     string fileName;

     S opAssign(S) const {
         writefln("deleting %s", fileName);    // <-- Oops.
         return this;
     }
}

union U {
     S s;
     string file;
}

void main() {
     U u;
     u.file = "important_file.txt";

     // This assignment is executed on an S that is not properly
     // initialized. The operation deletes an unrelated file.
     u.s = S.init;
}


Of course, users of unions must understand how bits of different types 
are shared and how that can cause trouble.

Ali



More information about the Digitalmars-d-learn mailing list