digitalmars.D - _moduleDtor() before gc_term() problem
- derick_eddington nospam.yashmoo.com (73/73) May 17 2005 I have a class who's destructor calls an object located at the top-level...
- Andrew Fedoniouk (10/94) May 17 2005 *I think* that in any casy relying on order of deletion
- Derek Parnell (93/111) May 17 2005 I don't think that the GC is the problem here. If you don't explicitly
- derick_eddington nospam.yashmoo.com (3/6) May 18 2005 'auto', of course! I totally forgot about that. I need to read through...
I have a class who's destructor calls an object located at the top-level of an imported module (the reference is in the static data segment; it's instantiated in the module constructor and explicitly delete'd in the module destructor because the object destructor must be run). The problem is the module destructor is being called before the client-class's destructor so the module-object is null when the client-class's destructor uses it, resulting in seg-fault. I think this is happening because phobos/internal/dmain2.d calls _moduleDtor() before gc_term(). This seems very inconvenient to me that modules are destructed before the GC collects/destructs the remaining objects because it seems to me those objects' destructors should be able to relying on using module services. I want to provide a standard object instance at module-level, and I must be certain that instance is destructed so I have to use explicit delete in the module destructor. This standard object allocates and deallocates resources for clients and client objects need to use it in their destructors to deallocate. Doesn't this seem like it should be possible? Am I missing something? Suggestions? For example: framework.d: ------------ ------------------------------------- myapp.d: ------- --------------------------------------------- $ dmd myapp.d framework.d $ ./myapp framework.d ~this() StandardObj.~this() MyThing.~this() Segmentation fault
May 17 2005
*I think* that in any casy relying on order of deletion of objects under any GC is not a good decision. In case of such conglomerate of objects I would consider its explicit destruction e.g. at the end of main or in module ctor. This needs such objects to be linked somehow - to be able to run through all of them and do some finalization (if design cannot be changed to avoid such dependencies). Andrew. <derick_eddington nospam.yashmoo.com> wrote in message news:d6ees9$1a6r$1 digitaldaemon.com...I have a class who's destructor calls an object located at the top-level of an imported module (the reference is in the static data segment; it's instantiated in the module constructor and explicitly delete'd in the module destructor because the object destructor must be run). The problem is the module destructor is being called before the client-class's destructor so the module-object is null when the client-class's destructor uses it, resulting in seg-fault. I think this is happening because phobos/internal/dmain2.d calls _moduleDtor() before gc_term(). This seems very inconvenient to me that modules are destructed before the GC collects/destructs the remaining objects because it seems to me those objects' destructors should be able to relying on using module services. I want to provide a standard object instance at module-level, and I must be certain that instance is destructed so I have to use explicit delete in the module destructor. This standard object allocates and deallocates resources for clients and client objects need to use it in their destructors to deallocate. Doesn't this seem like it should be possible? Am I missing something? Suggestions? For example: framework.d: ------------ ------------------------------------- myapp.d: ------- --------------------------------------------- $ dmd myapp.d framework.d $ ./myapp framework.d ~this() StandardObj.~this() MyThing.~this() Segmentation fault
May 17 2005
On Wed, 18 May 2005 04:04:25 +0000 (UTC), derick_eddington nospam.yashmoo.com wrote:I have a class who's destructor calls an object located at the top-level of an imported module (the reference is in the static data segment; it's instantiated in the module constructor and explicitly delete'd in the module destructor because the object destructor must be run). The problem is the module destructor is being called before the client-class's destructor so the module-object is null when the client-class's destructor uses it, resulting in seg-fault. I think this is happening because phobos/internal/dmain2.d calls _moduleDtor() before gc_term(). This seems very inconvenient to me that modules are destructed before the GC collects/destructs the remaining objects because it seems to me those objects' destructors should be able to relying on using module services.I don't think that the GC is the problem here. If you don't explicitly delete the 'standardObj' then the GC doesn't even call that object's dtor. It is the explicit delete that is nullifying the standardObj instance. That and the fact that the module dtors are called before the MyThing dtor.I want to provide a standard object instance at module-level, and I must be certain that instance is destructed so I have to use explicit delete in the module destructor. This standard object allocates and deallocates resources for clients and client objects need to use it in their destructors to deallocate. Doesn't this seem like it should be possible? Am I missing something? Suggestions?If you use the 'auto' keyword on the MyThing instance, the D will call its dtor as soon as it goes out of scope, which is before any module dtors get called. Reworked example: framework.d: ------------ import std.stdio; StandardObj standardObj; static this() { writefln("new %s", __FILE__); standardObj = new StandardObj; } static ~this() { writefln("Enter %s ~this()", __FILE__); delete standardObj; writefln("Exit %s ~this()", __FILE__); } class StandardObj { this() { writefln("new StandardObj"); } void useIt () { writefln("%s.useIt()", this); } ~this() { writefln("%s.~this()", this); } } ------------------------------------- myapp.d: ------- import std.stdio; import framework; static this() { writefln("new %s", __FILE__); } static ~this() { writefln("%s ~this()", __FILE__); } class MyThing { this() { writefln("new MyThing"); } ~this () { writefln("%s.~this()", this); framework.standardObj.useIt(); } } void main () { auto MyThing myThing = new MyThing; } --------------------------------------------- C:\temp>build myapp Path and Version : z:\util\build.exe v2.08(935) built on Tue May 17 14:34:07 2005 z:\dmd\bin\..\..\dm\bin\link.exe myapp+framework,myapp.exe,,user32+kernel32,myapp.def/noi; C:\temp>myapp new framework.d new StandardObj new myapp.d new MyThing MyThing.~this() StandardObj.useIt() myapp.d ~this() Enter framework.d ~this() StandardObj.~this() Exit framework.d ~this() C:\temp> -- Derek Melbourne, Australia 18/05/2005 2:49:57 PM
May 17 2005
In article <1k520ou5lu21t$.1f8in1jvvfoqd$.dlg 40tude.net>, Derek Parnell says...If you use the 'auto' keyword on the MyThing instance, the D will call its dtor as soon as it goes out of scope, which is before any module dtors get called.'auto', of course! I totally forgot about that. I need to read through all the docs again, and this should have been in digitalmars.D.learn :) Thanks!
May 18 2005