Static destructors called before class instance destructors

rkreis elite01 at gmx.de
Sat Jul 21 13:53:53 PDT 2007


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'

with GDC 0.23 and DMD 1.018. This shows that the instance destructor 
accesses a static variable that has been modified by the static 
destructor. I can't think of any workaround.
In my opinion, it would be better if static destructors were only called 
after all unreachable class instances have been destructed. That 
wouldn't break static destructors accessing static references to class 
instances.
If one of those classes also depends on the static destructor not having 
run, that's a circular dependency to which I can't find a satisfying 
solution. For those cases, I suggest the current behavior, or a compile 
time error (which is hard to implement, I believe). Anyway, easily 
accessing static variables after the static destructor has run doesn't 
sound right.

See you soon.



More information about the Digitalmars-d mailing list