Missing destructor call using clear and base interface ref.

Ali Çehreli acehreli at yahoo.com
Mon Aug 6 13:46:45 PDT 2012


On 08/06/2012 06:59 AM, Roberto Delfiore wrote:
 > See the following code:
 >
 > interface A{
 > }
 >
 > class B : A{
 > this(string name){this.name = name;}
 > ~this(){
 > writefln("Destructor %s", name);
 > }
 > string name;
 > }
 >
 > void main(){
 > B b0 = new B("b0");
 > B b1 = new B("b1");
 >
 > A a = b0;
 > clear(a);
 >
 > clear(b1);
 > }
 >
 > Output:
 > Destructor b1
 >
 > dmd 2.059
 >
 > Why is the B destructor not invoked in the first clear?
 >
 > Expected output:
 > Destructor b0
 > Destructor b1
 >

Interesting.

I've tested the code with 2.060 after replacing 'clear' with 'destroy' 
(not required here, but because clear will be deprecated):

import std.stdio;

interface A{
}

class B : A{
     this(string name){this.name = name;}
     ~this(){
         writefln("Destructor %s", name);
     }
     string name;
}

void main(){
     B b0 = new B("b0");
     B b1 = new B("b1");

     A a = b0;
     writeln("Before clear(a)");
     destroy(a);

     writeln("Before clear(b1)");
     destroy(b1);

     writeln("Leaving main");
}

I see both of the destructor calls but the first one is executed out of 
order:

Before clear(a)
Before clear(b1)
Destructor b1
Leaving main
Destructor b0    <-- Here

Making 'a' a B produces the expected output:

     B a = b0;

Before clear(a)
Destructor b0    <-- Now at expected time
Before clear(b1)
Destructor b1
Leaving main

I guess destroy() is a no-op on an interface because your not seeing the 
destructor's effect and my seeing it can be explained by the 
non-deterministic behavior of the GC regarding destructor calls: If it 
is up to the GC, the destructor calls are not guaranteed.

Do others know? Shouldn't destroy() work on an interface?

Ali



More information about the Digitalmars-d-learn mailing list