Simple answer, never allow an exception from a dtor!
The complicated answer. You only get really nailed if the exception escapes the dtor while another exception is active. The normal case for this is when you are already unwinding the stack from another exception and the object in question is destroyed. In that case if the exception escapes the dtor then std::terminate
is called, note you can put in your own handler for std::terminate
by calling std::set_terminate
. The default implementation of std::terminate
is to call abort.
To complicate things more, most functions that want to make any guarantee about their exception safety, mainly the basic guarantee or the strong guarantee, rely on the underlying types to themselves not throw in their dtor*
The real question is, what state would your program be in when this error occurs? How can you recover? Where should this recovery be handled? You need to look at your specific case and work these issues out. Sometimes it's just fine to catch the exception and ignore it. Other times you need to raise some red flags.
So the answer is: it allowed by C++ to throw an exception in a dtor, but you shouldn't ever allow it to escape.
*Here's a brief synopsis of the exception guarantees (here's a much longer article)
- Recap: Briefly define the Abrahams exception safety guarantees (basic,
strong, and nothrow).
The basic guarantee is that failed
operations may alter program state,
but no leaks occur and affected
objects/modules are still destructible
and usable, in a consistent (but not
necessarily predictable) state.
The strong guarantee involves
transactional commit/rollback
semantics: failed operations guarantee
program state is unchanged with
respect to the objects operated upon.
This means no side effects that affect
the objects, including the validity or
contents of related helper objects
such as iterators pointing into
containers being manipulated.
The nothrow guarantee means that
failed operations will not happen. The
operation will not throw an exception.