Static destructors called before class instance destructors

Sean Kelly sean at f4.ca
Mon Jul 23 00:32:24 PDT 2007


Tristam MacDonald wrote:
> Sean Kelly Wrote:
> 
>> rkreis wrote:
>>> Good day.
>>>
>>> Using derelict, I noticed bad behavior: The app segfaulted inside of 
>>> destructors. I later found out that derelict unloaded libraries and the 
>>> destructor, freeing resources, tried to call such unloaded functions. 
>>> This happens because a static destructor unloads all libraries. A simple 
>>> test case shows that static destructors can be called before all 
>>> instances are destructed. If an instance destructor then uses resources 
>>> freed by the static destructor, things become problematic.
>>>
>>> import std.stdio;
>>>
>>> class Dude {
>>>     private static char[] eek;
>>>
>>>     public this() {
>>>         writefln("Dude ctor");
>>>     }
>>>
>>>     public ~this() {
>>>         writefln("Dude dtor - eek is '%s'", eek);
>>>     }
>>>
>>>     public static this() {
>>>         writefln("Dude static ctor");
>>>         eek = "Everything up and running";
>>>     }
>>>
>>>     public static ~this() {
>>>         writefln("Dude static dtor");
>>>         eek = "You're doomed";
>>>     }
>>> }
>>>
>>> void main() {
>>>     Dude d = new Dude();
>>> }
>>> outputs
>>> Dude static ctor
>>> Dude ctor
>>> Dude static dtor
>>> Dude dtor - eek is 'You're doomed'
>> Funny, I've recently been trying to decide how to handle this exact 
>> situation.  When a D application shuts down, unreachable objects 
>> may/will be collected then static dtors are run.  After that, there may 
>> still be valid D objects floating around, either which the GC 
>> incorrectly thought were reachable or that were reachable through static 
>> references.  Should these objects never be finalized?  This would 
>> certainly be the easier/cleaner approach to take, but I'm not sure how I 
>> feel about leaving objects un-finalized.
>> Sean
> 
> DO they actually get finalised at the moment? I seem to have noticed that a lot of destructors aren't run at program termination, unless fullCollect() is explicitly called.

Not in Tango right now, no.  But I may at least perform a normal 
collection prior to the static dtors to clean up all the stuff that 
really is no longer being referenced.


Sean



More information about the Digitalmars-d mailing list