Thread overview
[dmd-internals] Nested Unions?
Oct 12, 2012
David Nadlinger
Oct 12, 2012
Iain Buclaw
Oct 12, 2012
Jonathan M Davis
Oct 12, 2012
Iain Buclaw
Oct 12, 2012
Jonathan M Davis
Oct 12, 2012
Jonathan M Davis
Oct 12, 2012
David Nadlinger
Oct 12, 2012
David Nadlinger
October 12, 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.
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals
October 12, 2012
On 12 October 2012 16:08, David Nadlinger <code@klickverbot.at> wrote:
> 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. _______________________________________________

Not what I can see.

(gdb) p u
$1 = {a = -889275714, this = 0xcafebabe}

Which concludes that - [1] yes a context pointer is included in the union layout, but [2] its value is never anything meaningful because it is still a field in a union.

I'd say this is a accepts invalid bug - unions should be POD only in my opinion.


Regards
-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On 10/12/12 11:43 AM, Iain Buclaw wrote:
> Which concludes that - [1] yes a context pointer is included in the
> union layout, but [2] its value is never anything meaningful because
> it is still a field in a union.

Definitely a bug.

> I'd say this is a accepts invalid bug - unions should be POD only in my opinion.

Agree, although by the TAWD principle things should just work.


Andrei

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On Friday, October 12, 2012 12:39:20 Andrei Alexandrescu wrote:
> Agree, although by the TAWD principle things should just work.

What's TAWD stand for? I can't find anything online explaining it, and if I've run into the term, I don't remember it.

- Jonathan M Davis
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On 12 October 2012 18:08, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> On Friday, October 12, 2012 12:39:20 Andrei Alexandrescu wrote:
>> Agree, although by the TAWD principle things should just work.
>
> What's TAWD stand for? I can't find anything online explaining it, and if I've run into the term, I don't remember it.
>

That Angry Welsh Dude.


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On 10/12/12 1:08 PM, Jonathan M Davis wrote:
> On Friday, October 12, 2012 12:39:20 Andrei Alexandrescu wrote:
>> Agree, although by the TAWD principle things should just work.
>
> What's TAWD stand for? I can't find anything online explaining it, and if I've
> run into the term, I don't remember it.

Turtles All the Way Down.

Andrei
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On Friday, October 12, 2012 13:17:42 Andrei Alexandrescu wrote:
> On 10/12/12 1:08 PM, Jonathan M Davis wrote:
> > On Friday, October 12, 2012 12:39:20 Andrei Alexandrescu wrote:
> >> Agree, although by the TAWD principle things should just work.
> > 
> > What's TAWD stand for? I can't find anything online explaining it, and if I've run into the term, I don't remember it.
> 
> Turtles All the Way Down.

Ah yes. That I've heard (though probably not before I heard Walter using it), but the acronym didn't click.

- Jonathan M Davis
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On Friday, October 12, 2012 18:17:12 Iain Buclaw wrote:
> That Angry Welsh Dude.

LOL. I wonder what kind of design principle _that_ would be.

- Jonathan M Davis
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On Fri, Oct 12, 2012 at 5:43 PM, Iain Buclaw <ibuclaw@ubuntu.com> wrote:
> Which concludes that - [1] yes a context pointer is included in the union layout, but [2] its value is never anything meaningful because it is still a field in a union.

Regarding (1), that's why I wrote _layout_, but I see how you could interpret it differently. In any case, you are right, DMD just tries to read from offset 0 to get the context pointer, which is also where a is stored.

David
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

October 12, 2012
On Fri, Oct 12, 2012 at 6:39 PM, Andrei Alexandrescu <andrei@erdani.com> wrote:
> On 10/12/12 11:43 AM, Iain Buclaw wrote:
>> I'd say this is a accepts invalid bug - unions should be POD only in my opinion.
> Agree, although by the TAWD principle things should just work.

I agree – bvut he question then is how to interpret TAWD, I guess. Most people are probably not even aware that unions can member methods. And by disallowing access to the outer scope, we would make unions behave exactly the same as static nested structs, which I think is not unreasonable.

David
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals