[Issue 15832] Crashing program when a helper template function is used to create a template struct

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sat Mar 26 07:51:26 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=15832

--- Comment #4 from ag0aep6g at gmail.com ---
(In reply to Atila Neves from comment #2)
> However, even with ref, the explanation isn't quite right: the delegate
> created in the constructor doesn't reference garbage - the GC should keep
> the memory alive.

I think I was a tiny bit off, but not by much. I did some more testing and now
I think this is what happens: A closure is allocated, but that closure
references the field of the struct on the stack. And that field is part of a
local variable, of course. So, the delegate references a local variable through
two indirections.

That way, stuff like this works:

----
struct S
{
    int field;
    int delegate() makeFieldGetter()
    {
        return {return field;};
    }
}

void main()
{
    S s;
    s.field = 1;
    auto getter = s.makeFieldGetter();
    assert(getter() == 1); /* passes */
    s.field = 2;
    assert(getter() == 2); /* passes, too */
}
----

If the closure would make a copy the field on the heap, then the second assert
wouldn't pass.

I don't know if this is the best way to handle the situation, or if it's
horribly broken, or something in between.

(In reply to Atila Neves from comment #3)
> Ok, I've looked into it a bit more and I think it's a bug. I @disabled
> this(this) and it still happens.

I think "moving" from one location to another is still allowed with a disabled
this(this). And "moving" means: make a copy, don't run the postblit, destroy
the source. So dmd is probably complying with the spec when it moves a
non-copyable struct instead of constructing it at the destination site.

I'm not sure, though, and dmd seems to be quite fickle about when it makes a
copy and when not: When I change `mock`'s implementation to `auto m =
Mock!T(f); return m;`, then dmd seems to not make a copy. So, yeah, this may
well be a bug in the implementation, but I'm not sure if the current behavior
is against the spec.

--


More information about the Digitalmars-d-bugs mailing list