Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-23 Thread Steven Schveighoffer via Digitalmars-d-learn

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


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-23 Thread Imperatorn via Digitalmars-d-learn

On Friday, 23 April 2021 at 10:36:40 UTC, Imperatorn wrote:

On Thursday, 22 April 2021 at 22:47:17 UTC, 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:

[...]

Even though the nanF should thus be 1.0, 0.0, etc...

[...]


This actually seems to be a bug related to order of declaration.

Try this

---
union
{
int[size][size] b;
int[size * size] a;
}
---


Lol, formatting. But u get the idea *very* clearly at least 


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-23 Thread Imperatorn via Digitalmars-d-learn

On Thursday, 22 April 2021 at 22:47:17 UTC, 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:

[...]

Even though the nanF should thus be 1.0, 0.0, etc...

[...]


This actually seems to be a bug related to order of declaration.

Try this

---
union
{
int[size][size] b;
int[size * size] a;
}
---


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-23 Thread Rekel via Digitalmars-d-learn

On Friday, 23 April 2021 at 00:55:50 UTC, H. S. Teoh wrote:

[...]
If you read the field during CTFE.  I've never tested 
initializing a union in CTFE then reading it at runtime, 
though. Not sure exactly what would happen in that case.



T


I'm not referring to reading non-initial variables, though Im 
surprised that's not possible?
In any case, it seems assigning values doesn't work during CTFE 
either ... And that is very disappointing to me to be quite 
honest...


This only seems to happen when I use CTFE to create a static 
singleton of the union by assigning to non-initial variables, I 
couldn't find anything in the docs that say I shouldn't, I might 
have missed something...
I really hope this is a bug... if its not, & assuming its not 
inevitable, this really shouldn't be a thing. Be it by design or 
limitation.


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-22 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Apr 22, 2021 at 11:44:51PM +, Rekel via Digitalmars-d-learn wrote:
> On Thursday, 22 April 2021 at 23:41:33 UTC, H. S. Teoh wrote:
> > On Thu, Apr 22, 2021 at 10:47:17PM +, Rekel via Digitalmars-d-learn
> > wrote:
> > > I'm not sure why this is happening, but after simplifying my code
> > > I traced it back to what the title may suggest.
> > 
> > Keep in mind that CTFE does not support reinterpretation via unions,
> > i.e., reading values from a different field in a union than was
> > assigned. If you assign field A to a union, then you cannot read field B
> > from that union in CTFE. You can only do this at runtime, not in CTFE.
[...]
> I'm not sure what you mean,
> do you mean if i were to read the field during CTFE, or even if i read
> the field during runtime after initializing it using CTFE?

If you read the field during CTFE.  I've never tested initializing a
union in CTFE then reading it at runtime, though. Not sure exactly what
would happen in that case.


T

-- 
Recently, our IT department hired a bug-fix engineer. He used to work for 
Volkswagen.


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-22 Thread Rekel via Digitalmars-d-learn

On Thursday, 22 April 2021 at 23:41:33 UTC, H. S. Teoh wrote:
On Thu, Apr 22, 2021 at 10:47:17PM +, Rekel via 
Digitalmars-d-learn wrote:
I'm not sure why this is happening, but after simplifying my 
code I traced it back to what the title may suggest.


Keep in mind that CTFE does not support reinterpretation via 
unions, i.e., reading values from a different field in a union 
than was assigned. If you assign field A to a union, then you 
cannot read field B from that union in CTFE. You can only do 
this at runtime, not in CTFE.



T


I'm not sure what you mean,
do you mean if i were to read the field during CTFE, or even if i 
read the field during runtime after initializing it using CTFE?


Re: CTFE Assignment to anonymous union shows unexpected behavior

2021-04-22 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Apr 22, 2021 at 10:47:17PM +, Rekel via Digitalmars-d-learn wrote:
> I'm not sure why this is happening, but after simplifying my code I
> traced it back to what the title may suggest.

Keep in mind that CTFE does not support reinterpretation via unions,
i.e., reading values from a different field in a union than was
assigned. If you assign field A to a union, then you cannot read field B
from that union in CTFE. You can only do this at runtime, not in CTFE.


T

-- 
There are two ways to write error-free programs; only the third one works.


CTFE Assignment to anonymous union shows unexpected behavior

2021-04-22 Thread Rekel via Digitalmars-d-learn
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 :(