[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
Fri Mar 25 15:53:24 PDT 2016


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

ag0aep6g at gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |ag0aep6g at gmail.com
         Resolution|---                         |INVALID

--- Comment #1 from ag0aep6g at gmail.com ---
(In reply to Atila Neves from comment #0)
> struct MockScope(T) {
>     this(T)(ref T oldFunc, T newFunc) {
>         _oldFuncPtr = &oldFunc;
[...]
>     }
[...]
> }
> 
> struct Mock(T) {
>     this(ref T func) {
[...]
>         _scope = MockScope!(T)(func, &inner);
>     }
[...]
> }
> 
> auto mock(T)(T f) {
>     return Mock!T(f);
> }
> 
> void main() {
>     //auto m = Mock!(typeof(dg))(dg); //this works
>     auto m = mock(dg); // this should be equivalent but crashes
[...]
> }

mock's parameter f is not ref. So it's constructing a Mock/MockScope that
references its local f. Once mock returns, the local f ceases to exists.
Dereferencing the pointer to it is bound to fail then.

When you change mock's parameter to ref, it no longer crashes in that way. But
it doesn't work either. It then boils down to this:

----
struct Mock {
    this(ref int delegate() func) {
        func = {return _return;};
    }
    int _return = 41;
}

Mock mock(ref int delegate() f) {
    return Mock(f);
}

void main() {
    int delegate() dg;
    version (good) auto m = Mock(dg); // works
    else auto m = mock(dg); // fails
    assert(dg() == 41);
    m._return = 42;
    assert(dg() == 42);
}
----

I think I can see the problem here, and it's similar to be above: When mock
returns, the Mock is copied. But the delegate that's created in the constructor
references the old, temporary location. When mock returns, the delegate gets
invalidated. It references garbage from then on.

As far as I see, everything works as expected here, so I'm closing this as
invalid. Please reopen if I have missed something, or if you think that
something should work differently.

--


More information about the Digitalmars-d-bugs mailing list