On 06.09.2016 14:56, Johan Engelen wrote:
Hi all,
  I have a question about the validity of this code:
```
void main()
{
    struct A {
        int i;
    }
    struct S
    {
        union U
        {
            A first;
            A second;
        }
        U u;

        this(A val)
        {
            u.second = val;
            assign(val);
        }

        void assign(A val)
        {
            u.first.i = val.i+1;
        }
    }
    enum a = S(A(1));

    assert(a.u.first.i == 2);
}
```

My question is: is it allowed to assign to a field of a struct inside a
union, without there having been an assignment to the (full) struct before?
...

I don't think so (although your case could be made to work easily enough). This seems to be accepts-invalid. Another case, perhaps demonstrating more clearly what is going on in the compiler:

float foo(){
    union U{
        int a;
        float b;
    }
    U u;
    u.b=1234;
    u.a=3;
    return u.b; // error
}
pragma(msg, foo());


float bar(){
    struct A{ int a; }
    struct B{ float b; }
    union U{
        A f;
        B s;
    }
    U u;
    u.s.b=1234;
    u.f.a=0;
    return u.s.b; // ok
}
pragma(msg, bar()); // 1234.00F

The compiler allows it, but it leads to a bug with CTFE of this code:
the assert fails.
(changing `enum` to `auto` moves the evaluation to runtime, and all
works fine)

Reported here: https://issues.dlang.org/show_bug.cgi?id=16471.


Reply via email to