www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Constructors and exceptions

reply David Tiktin <dtiktin nospam.totally-bogus.com> writes:
Is it the expected behavior in D for the destructor of an object to 
be called even though the constructor throws an exception?

The following program prints:

  Error: Z ctor exception.
  Z dtor.

[code]

import std.c.stdio;
import std.gc;

class Z
{
  this(int i)
  {
    if (i > 0)
    {
      throw new Exception("Z ctor exception.");
    }

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

int
main(char[][] argv)
{
  try
  {
    Z z = new Z(66);
  }
  catch(Object o)
  {
    printf("Error: %.*s\n", o.toString())
  }

  /* Call the garbage collector */
  fullCollect();

  return 0;
}

[/code]

The same behavior occurs with an auto class whose constructor throws.

Dave

-- 
D.a.v.i.d  T.i.k.t.i.n
t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m
Jul 13 2004
parent reply David Tiktin <dtiktin nospam.totally-bogus.com> writes:
On 13 Jul 2004, David Tiktin <dtiktin nospam.totally-bogus.com> 
wrote:

 Is it the expected behavior in D for the destructor of an object to 
 be called even though the constructor throws an exception?
OK, this must be a stupid question because I asked it twice (once in digitalmars.D.bugs, once here) and didn't get a response in either place. I may be clueless (it's happened before!), but if so, could someone please just say so and give me a clue? I appreciate the fact that D supports multiple paradigms (to say the least) including grabage collection and deterministic destruction. Most of my OOP experience is with C++ where I get only deterministic destruction. In C++, the destructor is not called on an object if an exception was thrown by the object's constructor. So in the destructor, the programmer can assume the constructor completed successfully and (if you've been careful otherwise), that the object is in a known state. This is not the case in D, either for regular or for auto classes, as I think the code I posted shows. D calls the destructor even if the constructor throws. If this is by design, I guess that's OK, although it seems inelegant to me. Still, there are options. Destructors for classes whose constructor can throw can simply be written under the assumption that the object may not be in a known state, for instance, may not obey a class invariant. Or constructors for such classes will have to catch any exceptions and put the object into a known (failed) state before rethrowing (and destructors will have to check if the object is in a failed state). Or maybe throwing from a constructor will just be something you don't want to do in D if it would make a difference to the destructor. I just want to know: Is this by design? Does the D language specify that the destructor is called even if the constructor throws? Dave -- D.a.v.i.d T.i.k.t.i.n t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m
Jul 16 2004
parent "Matthew" <admin stlsoft.dot.dot.dot.dot.org> writes:
"David Tiktin" <dtiktin nospam.totally-bogus.com> wrote in message
news:Xns952871B74593dtiktinnospambogusco 63.105.9.61...
 On 13 Jul 2004, David Tiktin <dtiktin nospam.totally-bogus.com>
 wrote:

 Is it the expected behavior in D for the destructor of an object to
 be called even though the constructor throws an exception?
OK, this must be a stupid question because I asked it twice (once in digitalmars.D.bugs, once here) and didn't get a response in either place. I may be clueless (it's happened before!), but if so, could someone please just say so and give me a clue? I appreciate the fact that D supports multiple paradigms (to say the least) including grabage collection and deterministic destruction. Most of my OOP experience is with C++ where I get only deterministic destruction. In C++, the destructor is not called on an object if an exception was thrown by the object's constructor. So in the destructor, the programmer can assume the constructor completed successfully and (if you've been careful otherwise), that the object is in a known state. This is not the case in D, either for regular or for auto classes, as I think the code I posted shows. D calls the destructor even if the constructor throws.
It's a bug, plain and simple. Calling a dtor on an uninitialised object is meaningless Of course, those parts already constructed must be destroyed.
 If this is by design, I guess that's OK, although it seems inelegant
 to me.  Still, there are options.  Destructors for classes whose
 constructor can throw can simply be written under the assumption that
 the object may not be in a known state, for instance, may not obey a
 class invariant.  Or constructors for such classes will have to catch
 any exceptions and put the object into a known (failed) state before
 rethrowing (and destructors will have to check if the object is in a
 failed state).  Or maybe throwing from a constructor will just be
 something you don't want to do in D if it would make a difference to
 the destructor.

 I just want to know: Is this by design?  Does the D language specify
 that the destructor is called even if the constructor throws?

 Dave

 -- 
 D.a.v.i.d  T.i.k.t.i.n
 t.i.k.t.i.n [at] a.d.v.a.n.c.e.d.r.e.l.a.y [dot] c.o.m
Jul 16 2004