www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is legal in a destructor?

reply Lutger <lutger.blijdestijn gmail.com> writes:
I'm having some trouble understanding exactly what is and what isn't 
legal to do in a (non-auto) destructor. I'm thinking about these 
specifically:

- using the 'this' pointer as a parameter to make calls to another (from 
another class or free) function.
- calling member functions.
- referencing delegates to member functions.
- referencing data fields with types like int.

Also, is there a way to have the garbage collector run and collect dead 
objects without the delete expression, so as to experiment with the 
behavior?

The spec says: "When the garbage collector calls a destructor for an 
object of a class that has members that are references to garbage 
collected objects, those references are no longer valid. This means that 
destructors cannot reference sub objects. This rule does not apply to 
auto objects or objects deleted with the DeleteExpression."
Aug 27 2006
next sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Lutger wrote:
 Also, is there a way to have the garbage collector run and collect dead 
 objects without the delete expression, so as to experiment with the 
 behavior?

# static import std.gc ; # # class Foo { # /* ... */ # } # # void main () { # Foo f = new Foo; # f = null; # std.gc.fullCollect(); # } http://digitalmars.com/d/phobos/std_gc.html -- Chris Nicholson-Sauls
Aug 27 2006
prev sibling next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Lutger" <lutger.blijdestijn gmail.com> wrote in message 
news:ecruhp$2hug$1 digitaldaemon.com...
 I'm having some trouble understanding exactly what is and what isn't legal 
 to do in a (non-auto) destructor. I'm thinking about these specifically:

 - using the 'this' pointer as a parameter to make calls to another (from 
 another class or free) function.
 - calling member functions.
 - referencing delegates to member functions.
 - referencing data fields with types like int.

As a general rule, you shouldn't try to access any GC'ed memory within a destructor. This means most things allocated by your program, such as references to other class instances, arrays, and blocks of memory allocated by 'new'. When the destructor is run, the 'this' pointer is still valid, so you can call other member functions and use it as a parameter, but again, those functions shouldn't access GC'ed memory. I mostly use destructors to clean up non-GC'ed resources, such as system resources (file handles, COM interfaces etc.). I also set references to GC'ed memory to null, which isn't really required, but it might make the GC's job a little easier.
Aug 27 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
Lutger wrote:
 I'm having some trouble understanding exactly what is and what isn't 
 legal to do in a (non-auto) destructor. I'm thinking about these 
 specifically:
 
 - using the 'this' pointer as a parameter to make calls to another (from 
 another class or free) function.
 - calling member functions.
 - referencing delegates to member functions.

The three above things are only legal if the functions are final or if you can be certain you are calling them from the most derived class instance. Otherwise, there is a possibility that you will be calling into an already destroyed portion of the object. For example: class C { ~this() { fn(); } void fn() { printf( "default impl\n" ); } } class D : C { this() { val = cast(int*)malloc(int.sizeof); *val = 5; } ~this() { free(val); } void fn() { printf( "%d\n", *val ); } private int* val; } D d = new D; delete d; Here, C's dtor calls the virtual function fn, which attempts to print val after the memory allocated for val has been freed by D's dtor. So the function may print garbage or you may get an access violation.
 - referencing data fields with types like int.

Should be fine. Sean
Aug 29 2006