Thread overview
[Issue 6437] New: Refcounted calls dtor before ctor, never calls dtor for globals
Aug 04, 2011
Andrej Mitrovic
Jan 12, 2012
Ferdinand Majerech
Mar 09, 2012
Rob Jacques
Apr 20, 2012
Andrej Mitrovic
August 04, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=6437

           Summary: Refcounted calls dtor before ctor, never calls dtor
                    for globals
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: major
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrej.mitrovich@gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2011-08-04 14:23:06 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 12, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6437


Ferdinand Majerech <kiithsacmp@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kiithsacmp@gmail.com


--- Comment #1 from Ferdinand Majerech <kiithsacmp@gmail.com> 2012-01-12 12:29:56 PST ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 09, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6437


Rob Jacques <sandford@jhu.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sandford@jhu.edu


--- Comment #2 from Rob Jacques <sandford@jhu.edu> 2012-03-09 11:52:30 PST ---
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); }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6437


Andrej Mitrovic <andrej.mitrovich@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #3 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-04-19 18:34:00 PDT ---
(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).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------