Thread overview
Constructors and exceptions
Jul 13, 2004
David Tiktin
Jul 16, 2004
David Tiktin
Jul 16, 2004
Matthew
July 13, 2004
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
July 16, 2004
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
July 16, 2004
"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