Bug 6437 – Refcounted calls dtor before ctor, never calls dtor for globals
Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2011-08-04T14:23:00Z
Last change time
2012-04-19T18:34:00Z
Assigned to
nobody
Creator
andrej.mitrovich
Comments
Comment #0 by andrej.mitrovich — 2011-08-04T14:23:06Z
module globaldtors;
import std.typecons;
import std.stdio;
struct Foo
{
struct Payload
{
this(int x)
{
writeln("constructor called");
}
~this()
{
writeln("destructor called");
}
this(this) { assert(false); }
void opAssign(Foo.Payload rhs) { assert(false); }
}
private alias RefCounted!(Payload, RefCountedAutoInitialize.yes) Data;
Data data;
this (int x)
{
data = Data(x);
}
}
Foo foo;
void main()
{
/+
+ destructor called <- this should not happen
+ constructor called
+ <- where's the dtor call?
+/
// foo = Foo(1);
/+
+ destructor called <- this should not happen
+ constructor called
+ destructor called
+/
// auto bar = Foo(1);
}
Uncomment the two assignments individually to verify they print what's in the comments. Regardless if it's a global or not, a dtor is being called first for some reason, this looks like a bug.
But if the variable is also a global (TLS/shared doesn't matter), the dtor is not called on application exit.
Comment #1 by kiithsacmp — 2012-01-12T12:29:56Z
The destructor call seems to happen in struct
specialization of emplace(), which is called from
RefCounted._RefCounted.initialize() .
The result variable in emplace() has its destructor called when
it goes out of scope.(In reply to comment #0)
> module globaldtors;
> import std.typecons;
>
> import std.stdio;
>
> struct Foo
> {
> struct Payload
> {
> this(int x)
> {
> writeln("constructor called");
> }
>
> ~this()
> {
> writeln("destructor called");
> }
>
> this(this) { assert(false); }
> void opAssign(Foo.Payload rhs) { assert(false); }
> }
>
> private alias RefCounted!(Payload, RefCountedAutoInitialize.yes) Data;
> Data data;
>
> this (int x)
> {
> data = Data(x);
> }
> }
>
> Foo foo;
>
> void main()
> {
> /+
> + destructor called <- this should not happen
> + constructor called
> + <- where's the dtor call?
> +/
> // foo = Foo(1);
>
>
> /+
> + destructor called <- this should not happen
> + constructor called
> + destructor called
> +/
> // auto bar = Foo(1);
> }
>
> Uncomment the two assignments individually to verify they print what's in the
> comments. Regardless if it's a global or not, a dtor is being called first for
> some reason, this looks like a bug.
>
> But if the variable is also a global (TLS/shared doesn't matter), the dtor is
> not called on application exit.
Comment #2 by sandford — 2012-03-09T11:52:30Z
I just tried the example in D 2.058 and the extra dtors appear to have been fixed. The issue with globals and destruction still exists. For now, you can work around the problem using
static ~this() { typeid(foo).destroy(&foo1); }
Comment #3 by andrej.mitrovich — 2012-04-19T18:34:00Z
(In reply to comment #2)
> I just tried the example in D 2.058 and the extra dtors appear to have been
> fixed. The issue with globals and destruction still exists. For now, you can
> work around the problem using
>
> static ~this() { typeid(foo).destroy(&foo1); }
Yes it's fixed, thanks. The globals issue isn't really a bug since destruction of globals isn't guaranteed (IIRC the docs were updated recently to acknowledge this).