Why is dtor called for lazy parameter?

Simen Kjærås simen.kjaras at gmail.com
Fri Sep 18 20:19:22 UTC 2020


On Friday, 18 September 2020 at 14:14:31 UTC, Andrey Zherikov 
wrote:
> It seems that dtor is called at exit from lazy delegate, not at 
> exit form create():
> ======
>     create()
>     .do_something()
>     .do_lazy()
>     .do_something();
> ======
> Output:
> ======
> -> void test.main()
> -> test.do_lazy(lazy S s)
> -> test.create()
> 1 S test.S.this(int n)
> <- test.create()
> -> 1 test.do_something(S s)
> <- 1 test.do_something(S s)
> 1 void test.S.~this()
> ===-1
> <- test.do_lazy(lazy S s)
> -> 1703096 test.do_something(S s)
> <- 1703096 test.do_something(S s)
> <- void test.main()
> ======
>
> This doesn't even allow me to copy the value of 's' in 
> do_lazy().

You're right, I missed a step: do_lazy() takes a S, not a 
scoped!S, so the conversion from scoped!S to S happens after 
create() has returned and before the value is used in do_lazy. 
This explains my confusion earlier.

D's lazy is essentially the same as a delegate or function, so 
you could* rewrite to this (writelns omitted for clarity):

S do_lazy(S function() s) {
     return s();
}

void main() {
     (() => cast(S)create()) // Here
     .do_lazy()
     .do_something();
}

On the marked line, the cast from scoped!S to S happens, the 
scoped!S goes out of scope and the destructor is called.

*There may be differences, but for this discussion these are not 
important.

--
   Simen


More information about the Digitalmars-d-learn mailing list