On Tue, 10 Aug 2010 14:56:54 -0400, Mafi <m...@example.org> wrote:

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.

pushing an ignored argument on the stack doesn't matter. Basically, __dtor would always have a bool argument, and if the definition of the class had ~this(), it doesn't matter.

It's the reason you can have main either accept a string array or nothing.

-Steve

Reply via email to