digitalmars.D - Valid to assign to field of struct in union?
- Johan Engelen (38/38) Sep 06 2016 Hi all,
- Johan Engelen (8/11) Sep 06 2016 Before someone smart tries it, yes the code works with LDC, but
- Timon Gehr (28/66) Sep 06 2016 I don't think so (although your case could be made to work easily
- Johan Engelen (5/7) Sep 06 2016 What do you think of the original example [1] in the bug report
- Timon Gehr (3/10) Sep 07 2016 Would be better if it just worked, but if it doesn't, it should print a
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? 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.
Sep 06 2016
On Tuesday, 6 September 2016 at 12:56:24 UTC, Johan Engelen wrote:The compiler allows it, but it leads to a bug with CTFE of this code: the assert fails.Before someone smart tries it, yes the code works with LDC, but wait... swap the order of `first` and `second` in the union, and BOOM! Internally, CTFE of the code leads to a corrupt union initializer array. LDC and DMD do things a little differently in codegen. Oversimplified: LDC will use the first member of the union, DMD the last.
Sep 06 2016
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.00FThe 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.
Sep 06 2016
On Tuesday, 6 September 2016 at 17:58:44 UTC, Timon Gehr wrote:I don't think so (although your case could be made to work easily enough). This seems to be accepts-invalid.What do you think of the original example [1] in the bug report that uses `mixin Proxy!i;` ? [1] https://issues.dlang.org/show_bug.cgi?id=16471#c0
Sep 06 2016
On 06.09.2016 22:44, Johan Engelen wrote:On Tuesday, 6 September 2016 at 17:58:44 UTC, Timon Gehr wrote:Would be better if it just worked, but if it doesn't, it should print a diagnostic instead of just producing wrong code.I don't think so (although your case could be made to work easily enough). This seems to be accepts-invalid.What do you think of the original example [1] in the bug report that uses `mixin Proxy!i;` ? [1] https://issues.dlang.org/show_bug.cgi?id=16471#c0
Sep 07 2016