digitalmars.D - Issue with module destructor order
- Benjamin Thaut <code benjamin-thaut.de> Mar 26 2012
- Benjamin Thaut <code benjamin-thaut.de> Apr 08 2012
- Kevin Cox <kevincox.ca gmail.com> Apr 08 2012
- Timon Gehr <timon.gehr gmx.ch> Apr 08 2012
- "Martin Nowak" <dawg dawgfoto.de> May 23 2012
- "Martin Nowak" <dawg dawgfoto.de> May 23 2012
Hi,
I came across a issue with the order in which druntime calls the module
destructors. I created a small repro case for it:
file a.d:
module a;
import logger;
shared static this()
{
log("a init");
}
shared static ~this()
{
log("a deinit");
}
file b.d:
module b;
import mix;
class Foo
{
mixin logIt;
}
file logger.d:
module logger;
import std.stdio;
shared static this()
{
writefln("logger init");
}
void log(string message)
{
writefln(message);
}
shared static ~this()
{
writefln("logger deinit");
}
file main.d:
module main;
import std.stdio;
import a;
import b;
int main(string[] argv)
{
auto foo = new Foo();
writefln("main");
return 0;
}
mix.d:
module mix;
public import logger;
mixin template logIt()
{
static shared this()
{
log(typeof(this).stringof ~ " init");
}
static shared ~this()
{
log(typeof(this).stringof ~ " deinit");
}
}
Compile with: dmd a.d b.d logger.d main.d mix.d -oftest.exe
Running gives the following output:
logger init
a init
shared(Foo) init
main
a deinit
logger deinit
shared(Foo) deinit
That means that the logger module destructor is called before the b
module actually gets destructed which leads to the logger beeing used in
a destructed state. In my real world case this leads to a fiel operation
on a closed file handle. Is this intended behaviour or is this a bug? I
assume this happens because of the mixin template and the public import.
I'm using dmd 2.058.
--
Kind Regards
Benjamin Thaut
Mar 26 2012
Created bug ticket: http://d.puremagic.com/issues/show_bug.cgi?id=7855 -- Kind Regards Benjamin Thaut
Apr 08 2012
--0015175d004a3c9ae704bd29d488 Content-Type: text/plain; charset=UTF-8 On Mar 26, 2012 5:11 AM, "Benjamin Thaut" <code benjamin-thaut.de> wrote:Is this intended behaviour or is this a bug? I assume this happens
I'm using dmd 2.058. -- Kind Regards Benjamin Thaut
I don't think the order of destructors is defined. There would be no way to have semantic control because it wouldn't work when you link different files together. The only solution would be to have the compiler analyse the code and figure out what should be destructed first which would be and impressive feat. The solution to solving your problem is not to close the file object in the destructor and let the OS clean it up when your program terminates. --0015175d004a3c9ae704bd29d488 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <p><br> On Mar 26, 2012 5:11 AM, "Benjamin Thaut" <<a href=3D"mailto:c= ode benjamin-thaut.de">code benjamin-thaut.de</a>> wrote:<br> > Is this intended behaviour or is this a bug? I assume this happens bec= ause of the mixin template and the public import.<br> > I'm using dmd 2.058.<br> ><br> > -- <br> > Kind Regards<br> > Benjamin Thaut</p> <p>I don't think the order of destructors is defined. There would be no= way to have semantic control because it wouldn't work when you link di= fferent files together.=C2=A0 The only solution would be to have the compil= er analyse the code and figure out what should be destructed first which wo= uld be and impressive feat.</p> <p>The solution to solving your problem is not to close the file object in = the destructor and let the OS clean it up when your program terminates.</p> --0015175d004a3c9ae704bd29d488--
Apr 08 2012
On 04/08/2012 02:14 PM, Kevin Cox wrote:On Mar 26, 2012 5:11 AM, "Benjamin Thaut" <code benjamin-thaut.de <mailto:code benjamin-thaut.de>> wrote: > Is this intended behaviour or is this a bug? I assume this happens because of the mixin template and the public import. > I'm using dmd 2.058. > > -- > Kind Regards > Benjamin Thaut I don't think the order of destructors is defined. There would be no way to have semantic control because it wouldn't work when you link different files together. The only solution would be to have the compiler analyse the code and figure out what should be destructed first which would be and impressive feat.
Actually that is what is normally done. (it is quite conservative though, cyclical imports where multiple modules have static constructors/destructors are just disallowed and terminate the program on startup.)The solution to solving your problem is not to close the file object in the destructor and let the OS clean it up when your program terminates.
This would be a workaround.
Apr 08 2012
mixin template logIt() { static shared this() { log(typeof(this).stringof ~ " init"); } static shared ~this() { log(typeof(this).stringof ~ " deinit"); } }
http://dlang.org/class.html#StaticConstructor
May 23 2012
mixin template logIt() { static shared this() { log(typeof(this).stringof ~ " init"); } static shared ~this() { log(typeof(this).stringof ~ " deinit"); } }
http://dlang.org/class.html#StaticConstructor
May 23 2012









Benjamin Thaut <code benjamin-thaut.de> 