Should destructors be able to tell who called them?

Mafi mafi at example.org
Tue Aug 10 11:56:54 PDT 2010


Am 10.08.2010 20:25, schrieb Steven Schveighoffer:
> One of the common problems of destructors is that they cannot assume any
> of their GC-allocated resources are valid when inside the destrutor.
>
> The spec says:
>
> 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. This rule does not apply
> to auto objects or objects deleted with the DeleteExpression, as the
> destructor is not being run by the garbage collector, meaning all
> references are valid.
>
> Let's analyze that last sentence (BTW, I think where it says auto, it
> should say scope). "This does not apply to objects deleted with the
> DeleteExpression..." Well, how the hell do you know while in the
> destructor whether you were called via delete/clear or from the GC? You
> don't. So the destructor *must* be written as if you are called from the
> GC, because the GC may be calling it, it is up to the user to determine
> whether your class will be destroyed via delete/clear or the GC. So you
> must assume worst case. Unless you declare your class as scope, which I
> don't even know if anyone does that anymore (I think it's scheduled for
> deprecation anyways).
>
> But, what if the destructor was given an idea of whether its resources
> are valid or not? Then you could do something different based on that
> input.
>
> For example, an object that wants to open a file can do so, and in the
> destructor, use the determination of validity to decide whether to close
> the file or not.
>
> This can be implemented by an optional parameter to the destructor
> that's always passed, but it's not necessary to use it. i.e. you could
> declare your destructor like this:
>
> ~this(bool deterministic)
> {
> if(deterministic) file.close();
> }
>
> or like this:
>
> ~this()
> {
> }
>
> Scope classes (if allowed to exist) or calls to clear will set
> deterministic to true. The GC will set it to false.
>
> This would make destructors a lot more useful. Thoughts?
>
> -Steve

Interestingly I had exactly the same idea a few hours ago as I red the 
discussions about clear. I just forgot about it without posting.

I think it's a good idea. The ignorant destructor (ie w/o parameter) 
defenition should be inetrnally rewritten to accept an ignored bool 
parameter. This would make the following thing a doubled and therfore 
incorrect definition.

class X {
   ~this(){}
   ~this(bool det){}
}

If the compiler then adds an overload for 'X.__dtor()' which simply 
calls 'X.__dtor(false)' [1], we should be totally compatible with 
existing code.

[1] IMO this should be false and not true but I'm not sure.


More information about the Digitalmars-d mailing list