What is different between constructors and destructors (with regard to throwing) is that
Firstly, destruction of objects is tied to unwinding, and unwinding happens when exceptions are thrown. Unwinding is not tied to construction of objects. That is to say, there is a relationship between destructors and exceptions already.
When some code is interrupted during the construction of an object, this can be safely handled. Resources can be rolled back as if the creation of the object had never been requested. Furthermore, it doesn't matter that subsequent code doesn't run, like the construction of other objects. In the case of destruction, it is essential that it be done properly, otherwise resources leak. It is not okay to abandon a destructor, because that is the last chance for cleaning up an object. Moreover, if the destructor is part of a chain of multiple calls, it is not okay for the remaining destructors to never be called. Neglect to execute destructors will lead to some permanent problem in the program.
Suppose you have a situation like this:
{
A a;
B b;
C c;
// ...
}
Suppose that the statments in the block throw, so the destructors for A, B and C are carried out in reverse order: C::~C
then ~B::B
and A::~A
. Suppose that C::~C
throws. This means that not only will the destruction of c
be incomplete, but that the destruction of B
and A
will not happen. The clean-up code for this statement block is simply abandoned.
What should the semantics be?
If none of the destructors can be abandoned in this situation, that means that C::~C
has to re-execute if it throws. But that will likely trigger an infinite loop.
Or, unwinding could still do the remaining destructors for b
and a
. But that still means that the C
destructor was abandoned and C
is not properly destroyed.