pocoproject/poco — pull request #538 by richard-telerik (2014-09-12 14:01:00+00:00)
Title: Ensure no exceptions from dtors; marked noexcept(true) in C++11

This is a rather extensive change. Here's the background:

In C++11 destructors are implicitly specified as "noexcept(true)". This means destructors are not expected to throw exceptions and that std::terminate() will be called instead if they do. And std::terminate() will abort and kill the process, terminating with an error message. Not desirable.

http://en.cppreference.com/w/cpp/language/destructor
>"If no exception-specification is provided, the exception-specification is one that that would be used by the implicitly-declared destructor (see below). In most cases, this is noexcept(true)."
>"the exception specification of the implicitly-defined destructor is noexcept(true)"

http://en.cppreference.com/w/cpp/language/noexcept_spec
>"If a search for a matching exception handler leaves a function marked noexcept or noexcept(true), std::terminate is called immediately."

I came across this issue when upgrading a medium codebase to use C++11 on MacOS, which is now the default since XCode 5.0.1. The app uses most of the Poco libs. At exit() the static variables in Poco (Mutex etc) would be destroyed first and my app's background-threads would then afterwards cause std::terminate() to be called because destructors used there would throw exceptions when those presumably always-available Poco resources no longer worked; e.g. locking a Mutex would now fail. It took me several days to pinpoint this problem and it involved many Poco-classes.

Because instances of any Poco-type can be alive upon exit, the only reliable *and maintainable* solution is to ensure that no Poco destructors can throw exceptions. Prior to C++11, avoiding destructor-exceptions was merely strongly recommended, but C++11 effectively mandates it - as in, "if your dtor throws the app will die".

That is what this fix contains.

As guideline I've chosen to guard any destructor-code that was not immediately obviously fail-safe. Destructors solely operating on the object's primitive members (doing count-- or calling delete, for instance) do not need guarding, on the assumption that the code is correct and the heap not corrupted. By any destructor that calls into unknown territory, i.e. other methods, have been wrapped into an exception-handler. Many destructors already had a suitable exception-handler and they have been left alone.

I realize this is a big change-set. And careful analysis may reveal that some destructors may not need it. However, cherry-picking which to fix seems hazardous at best. So, even though it's overwhelming I believe the alternative, having Poco potentially indirectly terminate the app, is worse.