destructor order

Jonathan M Davis jmdavisProg at gmx.com
Wed Jan 26 11:19:49 PST 2011


On Wednesday, January 26, 2011 07:53:29 Albin Breen wrote:
> Steven Schveighoffer Wrote:
> > See here: http://www.digitalmars.com/d/2.0/class.html#destructors
> > 
> > "The garbage collector is not guaranteed to run the destructor for all
> > unreferenced objects. Furthermore, the order in which the garbage
> > collector calls destructors for unreference objects is not specified.
> > This means that 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 may no longer be valid. This means
> > that destructors cannot reference sub objects."
> 
> Thanks! This means that the GC cannot be trusted to call destructors. I
> interpret that as "class destructors must be called manually".
> 
> Furthermore, The D Programming Language book states that: "...there is no
> delete operator. (D used to have a delete operator, but it was depre-
> cated.)" so you can't use that either.
> 
> In other words you are left with:
> 	clear(a);
> to manually call the destructor, which will also call the constructor again
> (this time with no parameters), and possibly (but not certainly) the
> destructor once more.
> 
> To be able to use clear() you will have to enforce RAII using structs (not
> garbage collected) or finally{} or scope constructs all the way from main
> in parallel with all your garbage collected code.
> 
> All in all, if class destructors cannot be guaranteed to execute by other
> means than the manual approach then should they be considered a liability?
> In Phobos std.socket a destructor is used to close() the socket.

Personally, I don't think that using class destructors is currently a good idea. 
Certainly, if you _need_ the destructor to run, then you probably need to 
rethink your design, since there's no guarantee that it's going to run. You can 
call clear(), but relying on your code doing that in the general case seems like 
a bad idea. Already, class destructors can't deal with other GC-allocated 
objects, so they're restricted to cleaning up other types of resources. If 
anything, I question that classes should even _have_ destructors. For structs, 
it makes great sense, but for classes... not so much. At best, they seem useable 
for stuff like file descriptors where you'd like them to be cleaned up when the 
object is destroyed if you forgot to do so by calling the appropriate close 
function or whatnot. But generally, it would be a bug in your code if you didn't 
release the file descriptor yourself (via the close function or whatever)

So, I'd argue that in the general case, you shouldn't be using class 
destructors. If your object really needs a destructor, then perhaps it should be 
a struct (on the stack, since structs on the heap _never_ get their destructors 
called IIRC).

- Jonathan M Davis


More information about the Digitalmars-d mailing list