[dmd-internals] Nested Unions?

David Nadlinger code at klickverbot.at
Fri Oct 12 08:08:30 PDT 2012


Earlier today, I was surprised to find out that DMD accepts the
following program:

---
extern(C) void printf(const char*, ...);

auto create() {
    int b = 0xdeadbeef;
    union U {
        int a;
        int member() { return a; }
        int outer() { return b; }
    }
    U u;
    u.a = 0xcafebabe;
    return u;
}

void main() {
    auto u = create();
    printf("%x\n", u.member());
    printf("%x\n", u.outer());
}
---

It segfaults at runtime, though, when trying to load from the nested
context pointer in U.outer(). Now, the question is: Is this really a
bug, or just an accepts-invalid issue?

I bring this up because Phobos actually contains a nested union
(albeit without accesses to the outer scope, "U2" in the std.conv unit
tests), which currently cause an assertion error in LDC [1].

So, do we want to support nested unions just like nested structs
(which would mean that every nested union would get a context
pointer), or should we just disallow access of outer scopes in union
member methods (which are quite exotic anyway).

I suppose the result of applying the "turtles all the way down" rule
differes from intuition here… C++ similarly disallows virtual
functions in unions, probably for the same reasons, i.e. avoiding
cases where compiler-added fields would change the union size.

David


@Andrei: Sorry for disappearing from IRC earlier, my battery went out…


[1] The reason for the DMD runtime crash is that no nested context
pointer is actually included in the union layout, which is caught at
compile time in LDC due to the fact that the LLVM IR is typed.


More information about the dmd-internals mailing list