Thread overview
[Issue 704] New: destructors are called even if the constructor throws an exception
Dec 21, 2006
d-bugmail
May 09, 2007
d-bugmail
Oct 29, 2007
d-bugmail
Jan 16, 2009
d-bugmail
Jan 16, 2009
d-bugmail
Jan 17, 2009
d-bugmail
Nov 20, 2011
Lionello Lunesu
December 21, 2006
http://d.puremagic.com/issues/show_bug.cgi?id=704

           Summary: destructors are called even if the constructor throws an
                    exception
           Product: D
           Version: 0.177
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: thomas-dloop@kuehne.cn


(originally posted by Sean Kelly <sean@f4.ca> on 2006-01-24 as
 news:dr5uqg$2hn7$1@digitaldaemon.com)

// This demonstrates incorrect behavior for auto class
// construction.  If an exception is thrown out of a
// class ctor then it is an incomplete object and its
// dtor should not be called.

import std.c.stdio;


auto class AutoClass
{
public:
    this()
    {
        printf( "ctor\n" );
        throw new Exception( "" );
    }

    ~this()
    {
        printf( "dtor\n" );
    }
}


void main()
{
    try
    {
        auto AutoClass c = new AutoClass();
    }
    catch( Exception e )
    {
        printf( "caught\n" );
    }
    printf( "continue\n" );
}
C:\code\d\bugs>dmd 101_1.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe 101_1,,,user32+kernel32/noi;

C:\code\d\bugs>101_1
ctor
caught
continue
dtor

test cases:
http://dstress.kuehne.cn/run/a/auto_14_A.d
http://dstress.kuehne.cn/run/a/auto_14_B.d


-- 

May 09, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=704


braddr@puremagic.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |major




------- Comment #1 from braddr@puremagic.com  2007-05-09 17:42 -------
Retesting with a newest version of the compiler (1.014), these two tests should probably be altered with s/auto/scope/ due to the changes in the language.

Also, throwing from a destructor is iffy behavior by itself.  Either way, they still hit the throw in the dtor.

However, fixing the throw from destructor issue like this:
     1  module dstress.run.a.auto_14_A;
     2
     3  import std.stdio;
     4
     5  bool dtorcalled = false;
     6
     7  auto class MyClass{
     8      this(){
     9          writefln("in ctor");
    10          throw new Exception("dummy");
    11      }
    12
    13      ~this(){
    14          writefln("in dtor");
    15          dtorcalled = true;
    16      }
    17  }
    18
    19  int main(){
    20      try{
    21          auto MyClass c;
    22          c = new MyClass();
    23      }catch{}
    24
    25      if(!dtorcalled){
    26          writefln("dtor not called");
    27          return 0;
    28      }else{
    29          writefln("dtor called");
    30          assert(0);
    31      }
    32
    33      assert(0);
    34  }

Results in:
in ctor
dtor not called
in dtor

So, there seems to be two issues here:
1) the dtor is being called at the wrong place, much after the scope it's
declared within has gone away.

2) it's being called at all due to the constructor exiting via throw.

Upgrading to severity major since I can't think of any work around and proper scope behavior is a fairly important language feature.


-- 

October 29, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=704


bugzilla@digitalmars.com changed:

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




------- Comment #2 from bugzilla@digitalmars.com  2007-10-28 23:27 -------
Works in dmd 1.022 and 2.007.


-- 

January 16, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=704


gide@nwawudu.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WORKSFORME                  |




------- Comment #3 from gide@nwawudu.com  2009-01-16 06:05 -------
I noticed this issue in my code. I think the problem is that the following code should not be allowed.

   scope MyClass c; // or auto MyClass c;
   c = new MyClass();

The following code works correctly.
   scope MyClass c = new MyClass();

Maybe the tests should be changed in dstress.


-- 

January 16, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=704





------- Comment #4 from 2korden@gmail.com  2009-01-16 15:01 -------
I'm not sure whether it is a bug (unless specs specify other behavior).

Unlike C++, objects in D are fully constructed /before/ entering ctor and thus I would expect the dtor to be called even if ctor throws.


-- 

January 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=704





------- Comment #5 from samukha@voliacable.com  2009-01-17 06:12 -------
Default initializing object's fields doesn't mean full object construction. I do believe that an object should be considered constructed only if its constructor has completed successfully. Otherwise, the constructor should clean after itself and only deallocator (if any), but not destructor, should be run. Currently, deallocator is not run, meaning another bug in the compiler.


-- 

November 20, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=704


Lionello Lunesu <lio+bugzilla@lunesu.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lio+bugzilla@lunesu.com


--- Comment #6 from Lionello Lunesu <lio+bugzilla@lunesu.com> 2011-11-19 23:16:05 PST ---
(In reply to comment #5)
> Default initializing object's fields doesn't mean full object construction. I do believe that an object should be considered constructed only if its constructor has completed successfully. Otherwise, the constructor should clean after itself and only deallocator (if any), but not destructor, should be run. Currently, deallocator is not run, meaning another bug in the compiler.

for what it's worth: C# still calls the finalizer when the ctor throws.

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