www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 704] New: destructors are called even if the constructor throws an exception

reply d-bugmail puremagic.com writes:
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


-- 
Dec 21 2006
next sibling parent d-bugmail puremagic.com writes:
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.


-- 
May 09 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Oct 28 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Jan 16 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
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.


-- 
Jan 16 2009
prev sibling parent d-bugmail puremagic.com writes:
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.


-- 
Jan 17 2009