Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Constructor throws, but destructor gets called

Moderators: kris

Posted: 09/13/08 17:05:19

Hi, I have a problem with this code:

import tango.stdc.stdio;

class Foo {
    this() {
        printf("Foo ctor\n");
        throw new Exception("fail");
    }

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

void main() {
    Foo f = new Foo();
}

The destructor gets called although constructor has failed. Using dmd 1.035 + tango 0.99.7 the output is:

Foo ctor
object.Exception: fail
Foo dtor

When using phobos, it works ok and prints:

Foo ctor
Error: fail

What's going on here?

Author Message

Posted: 09/13/08 17:28:39

throwing an exception in the ctor does not exclude the creation of the class instance ... that happens before the ctor() code itself is actually invoked. The question is then perhaps this instead: should the dtor be invoked for 'partially' constructed class instances?

That is a difficult question to answer, particularly since dtors in D are almost entirely worthless in the general case (typical class members are not valid at the time of a dtor call, so you cannot refer to them).

Something else to contemplate: in many OO circles it is considered "poor form" to design ctors whereby they might throw exceptions. I'd imagine this specific dtor concern might have something to do with that?

Another way to think about this is to ponder whether such 'partially' constructed class instances should be ignored by the runtime, and thus never have the dtor invoked. I can see why people would complain about that too.

Also, it's not clear how you went about invoking the dtor ... there's no guarantee (in the D spec) that a given dtor will ever be executed. In particular, it may be that phobos does not invoke them upon process termination (there was a complaint at one time over how phobos took forever to exit a heap-intensive application, given the millions of dtors it was executing - IIRC that led to the removal of that code).

Posted: 09/13/08 18:11:07

D docs don't seem to mention throwing from ctors, but I found this http://d.puremagic.com/issues/show_bug.cgi?id=704, which seems to suggest that a failed ctor should not produce an object. This is how it is in C++ too http://www.gotw.ca/gotw/066.htm. Anyway, my confusion here was only the different way this works with tango. Thanks for help.

Posted: 09/13/08 18:34:10

It may not be different at all, depending on how you actually invoked the dtor. Tango has little to do with the ctor(), since that's pretty much down to the compiler. What you're seeing, I suspect, is related to whether or not a GC collection is executed during process termination. This is why I was asking how the dtor got invoked in your example.

To be clear, Tango does not change the way ctors are invoked or managed, and it does not change the manner in which objects are managed by the runtime or the GC itself. If there is any distinction in this arena, it's likely to be during process cleanup behaviour. Esentially, the Tango runtime treats the process itself just like an Object instance ... it runs the equivalent of a dtor on the process, which in turn may invoke class dtors. Phobos may not do that, which could explain the distinction you have noted