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?