www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Missing destructor call using clear and base interface ref.

reply "Roberto Delfiore" <roberto.delfiore gmail.com> writes:
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
Aug 06 2012
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Aug 06 2012
parent Denis Shelomovskij <verylonglogin.reg gmail.com> writes:
09.08.2012 12:36, Roberto Delfiore пишет:
 Thank you for your analysis, it's a very strange behavior. I
 still can not figure out if there is something I don't know or if
 it's is simply a bug.

 Good answer: Shouldn't destroy() work on an interface?

Filled an issue: http://d.puremagic.com/issues/show_bug.cgi?id=8527 -- Денис В. Шеломовский Denis V. Shelomovskij
Aug 09 2012
prev sibling parent "Roberto Delfiore" <roberto.delfiore gmail.com> writes:
Thank you for your analysis, it's a very strange behavior. I
still can not figure out if there is something I don't know or if
it's is simply a bug.

Good answer: Shouldn't destroy() work on an interface?

On Monday, 6 August 2012 at 20:46:45 UTC, Ali Çehreli wrote:
 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

Aug 09 2012