How to handle a destructor failure

Nov 10, 2008 at 12:37pm
How can I handle a failure in the destructor.?
A failure in the constructor can be handled by throwing an exception, where as throwing an exception in the destructor will lead to stack unwinding.

Experts can you help me with your inputs on handling this. Thanks in advance.
Nov 10, 2008 at 1:54pm
If a failure occurs during destruction of an object and the object cannot handle the failure itself, then throwing is the only option. It is the responsibility of the programmer to catch the exception at a point at which the failure can be handled properly.
Nov 10, 2008 at 11:25pm
You should never let an exception escape a constructor, or destructor. They should be caught and handled at that location.
Nov 11, 2008 at 1:05am
Er, *ahem*.

It is entirely OK and appropriate for a constructor to throw(). That's what exceptions are for.

It is not OK for a destructor to throw(). Ever.
If the error is sufficently horrible that it will damage your application's ability to function, then terminate the application. Otherwise, do something else: write to an error log, complain to the user, ignore it, whatever --just don't throw an exception.

For more reading, check out the C++FAQ-Lite, sections 17.2 and 17.3:
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2

Hope this helps.
Nov 11, 2008 at 10:38am
Destructors should be written in a way in which they cannot fail. If they can, it is a sign for bad design: a destructor should only free the resources, which won't fail. Any "high-level" de-initialization should take place in appropriate functions. This way, if they fail, the caller can decide what to do, and if required, the resources can be de-allocated without de-initialization by means of the destructor (which then cannot fail).
Nov 11, 2008 at 3:11pm
However it is a good practice to check the pointers even after the deallocation is given for a pointer in a destructor.
Hence a failure from destructor is definitely a bad design or code.
There were many scenarios/reports complaining that a destructor was not called when an exception thrown out of a constructor.
In a normal case a destructor is called automatically when an exception is thrown from the constructor or an object construction is failed.

My recommendation is to give a NULL check etc after every "new" call so that if an object's constructor (via new) is failed or incomplete by exception thrown, and it would be verified before any further processing. This would be done in conjunction with pointer reset to NULL after freeing the memory.

Check it out. Good luck :)
Last edited on Nov 11, 2008 at 3:44pm
Nov 11, 2008 at 4:30pm
My recommendation is to give a NULL check etc after every "new" call

That doesn't make sense if you didn't overwrite global operator new with global operator nothrow-new which isn't a good idea anyways (if you don't do something crazy, like writing an application which has to run without runtime environment).
The terms under which a destructor is called automatically is very well documented in the standard. Anyone complaining has either a bad compiler or doesn't know the standard.

In a normal case a destructor is called automatically when an exception is thrown from the constructor or an object construction is failed.

Which destructor(s)? If a constructor exits via the means of throwing an exception, the object isn't created and thus cannot be destroyed. However, already initialized base classes and (non static) members are destructed (in reverse order of construction, i.e. non-static member objects in reverse declaration order are first, virtual base classes depth-first, right-to-left last, and the rest in between), and the memory allocated by new is returned to the free store (if it wasn't a call of placement-new, that is).

If a failure occurs during destruction of an object and the object cannot handle the failure itself, then throwing is the only option.

Destructors that throw are evil. It is an stl requirement that the classes used in conjunction with the stl don't throw from the destructors, as well as it is a requirement of operator new[] and delete[] (calling new[] or delete[] for an class whose destructor might throw invokes undefined behavior: suppose the 2nd destructor of a 5-element array would throw when delete[] is invoked, what do you do? Propagating the exception would leave no way to delete the other 3 elements! Same in new[]: if during the construction an element throws, the rest is destroyed automatically. But if one of the destructors then throws, you are screwed).

You should never let an exception escape a constructor

Reporting errors from constructors was the initial idea of introducing exceptions into C++, since you cannot return error codes from them.
Last edited on Nov 11, 2008 at 4:39pm
Nov 12, 2008 at 4:52am
I am not sure about the new standard, but this was a hot topic discussed very often a while ago at MicroSoft forums.
As I had once encountered it with a MS VCpp compiler I still remember rewriting the code.

Actually it is called stack unwinding happens when a construction of object is failed.

Not sure if calling the destructors for an exception thrown from constructor is implementation dependent, but I am sure I still remember I seen a post recently discussing the same.
May be you are right, but not sure if it is varied from implementations.

But for now, I just checked it with a GCC (MingW) compiler and Borland 5.5 compiler. Both did not call the destructors when an exception thrown from constructor.

Good luck :)

Nov 12, 2008 at 4:59am
I just checked the MS VC forums. I guess the compiler VC2005 had that problem may be a bug, the I had encountered such destructor call using that compiler a while ago.
May be the current compiler is compliant to the new standard or the VC2005 had a bug, or it is implementation dependent.
Not sure.

Its late here. Good night guys :)
Nov 12, 2008 at 7:53am
MS isn't exactly known for its standard compliance. And since the "new" standard is from 1998, with only minor revisions in 2003 (which, to my knowledge, do not affect that topic at all, since it was pretty clear in the 1998 version), any compiler not implementing it should be replaced. It is pretty simple - no object, no destructor to call, period. There is nothing left to be implementation-defined. (And if you don't believe me, do yourself a favor and read the standard, not the MS docs...)
Topic archived. No new replies allowed.