Remember goto? Some distinguished gentlemen of the C++ programming trade look down on throwing from destructors as being eviler than using a goto. Standing base for such moral a judgment is that "a throwing destructor makes it impossible to write correct code and can shut down your application without any warning" .
Destructors in C++ are one essential ingredient to the Resource Acquisition Is Initialization (RAII) idiom, which can be resumed as follows: Resources (i.e. memory, sockets, file handles, etc) are acquired during the construction of an object. If an exception is thrown from anywhere in the code during the lifetime and after the object has been fully constructed, the C++ language rules guarantee that the object's destructor will be summoned.
Thus resources can be released gracefully and graciously by said destructor, even in the distasteful and exceptional eventuality of... an exception. The Programmer is relieved from the burdensome duty of having to release resources on every single possible code path.
RAII relieves the programmer from manually preventing leaks.
(Notice how nicely relieves and leaks go together).
If a destructor, invoked as part of the automatic cleanup that entails the throwing of an exception, decides to throw its own exception, then the system has but two choices: to go into an ambiguous state (now there are two outstanding exceptions, the original one, plus the destructor-thrown one) or... throw the towel.
It is C++ Standard behavior to follow the latter course: the towel is thrown from around the waist, the user is mooned and the program calls terminate(). Hasta la Vista, Baby. And for this reason, they say your destructors should never throw.
But what if there's not way to recover?
Let's consider a generic Lock object which may look something like this:
class Lock : boost::noncopyable
explicit Lock(T& mx) : mx_(mx)
The problem with the code above is that T::leave() may throw an exception (it may as well not throw, but one really cannot tell, since T is a template parameter).
An so I come to the conclusion of this post. I assert that the code above is just as good as it gets. Of course, T may be bound at compile time to a class that implements the leave method somewhat like this:
if (int resultCode = pthread_mutex_unlock(&mutex_))
If unlocking the resource fails, then a) something really bad must've happened (possibly a memory corruption?) and b) there is little, if anything, to do about restoring the system to a stable state.
I say let ye programme crash and burne.
What do You reckon?