www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Destructor called twice.

reply TheFlyingFiddle <none none.com> writes:
When writing some code to setup properties in a chain function 
manner I ran into some unexpected behavior with destructors.

Example:

struct S {
     int a, b;

     ref S foo(int b) {
         this.b = b;
         return this;
     }

     this(int ab) {
         this.a = this.b = ab;
         printf("ctor a=%d, b=%d\n", a, b);
     }

     ~this() {
         printf("dtor a=%d b=%d\n", a, b);
     }


}

void main()
{
     auto s0 = S(0).foo(1);
     auto s1 = S(1).foo(2).foo(3).foo(4);
     auto s2 = S(2);
     s2.foo(5).foo(6).foo(7);
}

//Output is
ctor 0
dtor 0 1
ctor 1
dtor 1 4
ctor a=2, b=2
dtor a=2 b=7
dtor 1 4
dtor 0 1


For s0,s1 the destructor is called twice but s2 works as I would 
expect.

Taking a look with dmd -vcg-ast provided this:
void main()
{
     S s0 = ((S __slS3 = S(, );) , __slS3).this(0).foo(1);
     try
     {
     	S s1 = ((S __slS4 = S(, );) , 
__slS4).this(1).foo(2).foo(3).foo(4);
     	try
     	{
     	    S s2 = s2 = S , s2.this(2);
     	    try
     	    {
     		s2.foo(5).foo(6).foo(7);
     	    }
     	    finally
     		s2.~this();
     	}
     	finally
     	    s1.~this();
     }
     finally
     	s0.~this();
     return 0;
}

The two extra dtor calls are not visible here but I guess they 
are caused by the temporary variables that are created and then 
go out of scope directly. Am I doing something wrong or is this a 
bug?
Feb 25 2018
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
add postblit debug prints, and you will see.
Feb 25 2018
parent TheFlyingFiddle <none none.com> writes:
On Sunday, 25 February 2018 at 21:35:33 UTC, ketmar wrote:
 add postblit debug prints, and you will see.
I get that it will call the postblit since it creates a temporary. What I expected though was that. auto s = S(0).foo(1); Would become something like: S s; s.__ctor(0).foo(1); But maybe this would not be consistent behavior? I'm wondering why it creates the temporary in the first place.
Feb 26 2018