auto classes and finalizers

kris foo at bar.com
Wed Apr 5 16:40:58 PDT 2006


Jarrett Billingsley wrote:
> "kris" <foo at bar.com> wrote in message news:e11fds$m0m$1 at digitaldaemon.com...
> 
>>Yes, it is. The "death tractors" (dtors in D) are notably less than useful 
>>right now. Any dependencies are likely in an unknown state (as you note), 
>>and then, dtors are not invoked when the program exits. From
>>what I recall, dtors are not even invoked when you "delete" an object? 
>>It's actually quite hard to nail down when they /are/ invoked :)
> 
> 
> They are invoked when you call delete.  This is how you do the deterministic 
> "list of special stuff" that you mention - you just 'delete' them all, 
> perhaps in a certain order.

I ended up using my own 'finalizer' since, back in the day, delete 
didn't invoke the dtor. It does now, so that's something. Objects that 
refer to anything external should probably have a close() method anyway 
~ which gets us back to what Mike had noted.

> 
> In fact, the dtors are also called on program exit - as long as they're not 
> in some kind of array.  I don't know if that's a bug, or by design, or a 
> foggy area of the spec, or a combination of all of the above.

Interesting. It does appear to do that now, whereas in the past it 
didn't. I remember a post from someone complaining that it took 5 
minutes for his program to exit because the GC was run to completion on 
all 10,000,000,000 objects he had (or something like that). The "fix" 
for that appeared to be "just don't cleanup on exit", which then 
sidestepped all dtors. It seems something changed along the way, since 
dtors do indeed get invoked at program termination for a simple test 
program (not if an exception is thrown, though). My bad.

Does this happen consistently, then? I mean, are dtors invoked on all 
remaining Objects during exit? At all times? Is that even a good idea?


> 
> 
>>Regardless; any "special resources" one would, somewhat naturally, wish
>>to cleanup via dtors have to be explicitly managed via other means. This
>>usually means a global application-list of "special stuff", which does not 
>>seem to jive with OOP very well?
> 
> 
> I kind of agree with you, but at the same time, I just take the stance that 
> although it's useful, _the GC can't be trusted_.  Unless a custom GC is 
> written for every program and every possible arrangement of data, it can't 
> know in what order to call dtors/finalizers and whatnot.  So I do end up 
> keeping lists of all types of objects that I want to be called 
> deterministically, and delete them on program exit.  I just leave the simple 
> / common stuff (throwaway class instances, string crap) to the GC.  That 
> just makes me feel a lot better and safer.

The GC is supposed to be your friend :)

That doesn't mean it should know about your design but, there again, it 
shouldn't abort it either. That implies any additional GC references 
held by a dtor Object really should be valid whenever that dtor is 
invoked. The fact that they're not relegates dtors to having 
insignificant value ~ which somehow doesn't seem right. Frankly, I don't 
clearly understand why they're in D at all ~ too little consistency.

> 
> In addition, I usually don't assume that any references a class holds are 
> valid in the dtor.  I leave the cleanup of other objects (like in Sean's 
> example) to the other objects' dtors.
> 
> 
>>On the face of it, it shouldn't be hard for the GC to invloke dtors in 
>>such a manner whereby dependencies are preserved ~ that would at least 
>>help. But then, the whole notion is somewhat worthless (in D) when it's 
>>implemented as a non-deterministic activity.
> 
> 
> Yeah, I was thinking about that, maybe instead of just looping through all 
> class instances linearly and deleting everything, just keep running GC 
> passes until the regular GC pass has no effect, and brute force the rest. 
> In this way, my method of "not deleting other objects in dtors" would delete 
> the instance of the LinkedList on the first pass, and then all the Nodes on 
> the second, since they are now orphaned. 

Yep

If references were still valid for dtors, and dtors were invoked in a 
deterministic manner, perhaps all we'd need is something similar to 
"scope(exit)", but referring to a global scope instead? Should the 
memory manager take care of the latter?



More information about the Digitalmars-d mailing list