The more we use RAII in C++, the more we find ourselves with destructors that do non-trivial deallocation. Now, deallocation (finalization, however you want to call it) can fail, in which case exceptions are really the only way to let anybody upstairs know of our deallocation problem. But then again, throwing-destructors are a bad idea because of the possibility of exceptions being thrown during stack unwinding. std::uncaught_exception()
lets you know when that happens, but not much more, so aside from letting you log a message before termination there's not much you can do, unless you're willing to leave your program in an undefined state, where some stuff is deallocated/finalized and some not.
One approach is to have no-throw destructors. But in many cases that just hides a real error. Our destructor might, for example, be closing some RAII-managed DB connections as a result of some exception being thrown, and those DB connections might fail to close. This doesn't necessarily mean we're ok with the program terminating at this point. On the other hand, logging and tracing these errors isn't really a solution for every case; otherwise we would have had no need for exceptions to begin with. With no-throw destructors we also find ourselves having to create "reset()" functions that are supposed to be called before destruction - but that just defeats the whole purpose of RAII.
Another approach is just to let the program terminate, as it's the most predictable thing you can do.
Some people suggest chaining exceptions, so that more than one error can be handled at a time. But I honestly never actually seen that done in C++ and I've no idea how to implement such a thing.
So it's either RAII or exceptions. Isn't it? I'm leaning toward no-throw destructors; mainly because it keeps things simple(r). But I really hope there's a better solution, because, as I said, the more we use RAII, the more we find ourselves using dtors that do non-trivial things.
Appendix
I'm adding links to interesting on-topic articles and discussions I've found:
- Throwing Destructors
- StackOverflow discussion on the problems with SEH
- StackOverflow discussion on throwing-destructors (thanks, Martin York)
- Joel on Exceptions
- SEH Considered Harmful
- CLR Exception Handling which also touches on exception chaining
- Herb Sutter on std::uncaught_exception and why it's not as useful as you think
- Historical discussion on the matter with interesting participants (long!)
- Stroustrup explaining RAII
- Andrei Alexandrescu's Scope Guard