www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Destruction Sequence: module and classes defined within

reply vano <ivan.melnychuk+news gmail.com> writes:
The code below:
     module used;

     import std.stdio;

     class ClassA {
         this()  { writeln("A ctor"); }
         ~this() { writeln("A dtor"); }
     }

     static this()  { writeln("used.sctor"); }
     static ~this() { writeln("used.sdtor"); }

     void main() {
         auto a = new ClassA();
     }
produces the following output (DMD v2.049):
     used.sctor
     A ctor
     used.sdtor
     A dtor

The question is: should the module be allowed to be unloaded before all 
module-level objects/structures are destructed/unloaded?
Oct 05 2010
parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote:

 The code below:
      module used;
 
      import std.stdio;
 
      class ClassA {
          this()  { writeln("A ctor"); }
          ~this() { writeln("A dtor"); }
      }
 
      static this()  { writeln("used.sctor"); } static ~this() {
      writeln("used.sdtor"); }
 
      void main() {
          auto a = new ClassA();
      }
 produces the following output (DMD v2.049):
      used.sctor
      A ctor
      used.sdtor
      A dtor
 
 The question is: should the module be allowed to be unloaded before all
 module-level objects/structures are destructed/unloaded?

I'm no expert on this, but I think it has to be that way. Consider this: class Foo { ... } Foo foo; static this() { foo = new Foo; } static ~this() { foo.doStuff(); } So you see, if foo had already been destroyed and garbage collected, my program would have crashed when the module static destructor was run. Thus, I guess, running the garbage collector for the final time has to be one of the last things done on program shutdown, after running all module destructors. -Lars
Oct 06 2010
parent Lutger <lutger.blijdestijn gmail.com> writes:
Lars T. Kyllingstad wrote:

 On Tue, 05 Oct 2010 23:25:36 +0200, vano wrote:
 
 The code below:
      module used;
 
      import std.stdio;
 
      class ClassA {
          this()  { writeln("A ctor"); }
          ~this() { writeln("A dtor"); }
      }
 
      static this()  { writeln("used.sctor"); } static ~this() {
      writeln("used.sdtor"); }
 
      void main() {
          auto a = new ClassA();
      }
 produces the following output (DMD v2.049):
      used.sctor
      A ctor
      used.sdtor
      A dtor
 
 The question is: should the module be allowed to be unloaded before all
 module-level objects/structures are destructed/unloaded?

I'm no expert on this, but I think it has to be that way. Consider this: class Foo { ... } Foo foo; static this() { foo = new Foo; } static ~this() { foo.doStuff(); } So you see, if foo had already been destroyed and garbage collected, my program would have crashed when the module static destructor was run. Thus, I guess, running the garbage collector for the final time has to be one of the last things done on program shutdown, after running all module destructors. -Lars

In this case however, foo is still referenced whereas in the original example 'a' is unreferenced after main exits. I could only find this in the spec: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects." * From reading the spec, I think that all one can conclude is that after main unreferenced objects may be finalized any time, or not at all. * http://www.digitalmars.com/d/2.0/class.html#Destructor
Oct 08 2010