CTFE Assignment to anonymous union shows unexpected behavior
Steven Schveighoffer
schveiguy at gmail.com
Fri Apr 23 12:54:19 UTC 2021
On 4/22/21 6:47 PM, Rekel wrote:
> I'm not sure why this is happening, but after simplifying my code I
> traced it back to what the title may suggest. The original cause of my
> issues being summarized by debug print statements returning a union as:
>> Mat([nanf, nanF, . . . .], [[1.0F, 0.0F, . . . .])
> Even though the nanF should thus be 1.0, 0.0, etc...
>
> This is example code that describes when this happens:
>
> ```d
> import std.stdio;
>
> struct Apple(uint size) {
> union {
> int[size * size] a;
> int[size][size] b;
> }
>
> static immutable typeof(this) pie = _pie();
> private static typeof(this) _pie() pure {
> typeof(this) result;
> static foreach (i; 0 .. size)
> static foreach (j; 0 .. size)
> //result.a[i + j * size] = 1; // Works
> result.b[i][j] = 1; // Fails
> return result;
> }
> }
>
> void main() {
> Apple!(4) a = Apple!(4).pie;
> writeln(a.a);
> writeln(a.b);
> }
> ```
>
> The working code changes the first integers to 1, the failing version
> keeps them at 0.
>
> What's the reason for this? Logically this doesn't seem troublesome to
> me, and if assigning to non-initial anonymous union varialbes isn't
> possible(?!) that would be pretty bad, and I'd be in for quite some
> trouble in my actual code :(
I think this is a bug. For sure, the only 2 valid options are, it should
compile and do what you are expecting, or not compile.
CTFE unions are (I think) implemented as a "tagged" union, where only
one value is set. When you assign to a *part* of b, you are assigning to
something that isn't being used.
Normally, in CTFE, using a union member that isn't set is an error
(compile-time because CTFE).
If you assign to b all at once, it works:
```d
private static typeof(this) _pie() pure {
typeof(this) result;
typeof(b) val;
static foreach (i; 0 .. size)
static foreach (j; 0 .. size)
val[i][j] = 1;
result.b = val;
return result;
}
```
I think the compiler is allowing the usage of a part of b without the
tag being updated. Probably the right answer is, setting an element of b
should be an error, or it should switch the tag (if the union was never
set).
BTW, I think the fact that the union members are arrays is important.
Please file a bug.
-Steve
More information about the Digitalmars-d-learn
mailing list