...
Exceptions thrown in destructors of objects with static storage duration or in constructors of namespace-scope objects with static storage duration are not caught by a function-try-block on
main()
. Exceptions thrown in destructors of objects with thread storage duration or in constructors of namespace-scope objects with thread storage duration are not caught by a function-try-block on the initial function of the thread.
To illustrate using an example:
Non-Compliant Code Example
In the following non-compliant example, the constructor of global
may throw an exception during program startup. This exception is not caught by the function-try-block on main()
, resulting in a call to std::terminate()
. Similarly, the destructor of the local_static
object defined in function f(()
may throw an exception during program termination. This exception is also not caught by the function-try-block on main()
, again resulting in a call to std::terminate()
.
Code Block | ||
---|---|---|
| ||
static const std::string global("...");
void f() {
static const struct LocalClass {
| ||
Code Block | ||
struct Foo { Foo(); // may throw }; Foo A; void bar... ~LocalClass() { if (error_detected) throw std::runtime_error("..."); } static Foo B} local_static; } int main() try { barf(); // other executable statements } catch(...) { // will catchhandle exceptions thrown during fromthe bar()call andto // f() and any other executable statements in the try block // block above // IMPORTANT: will not catch exceptions thrown // from the constructor of theglobal globalor objectthose Afrom // or those from the destructor of the static local_static defined in f() // localand objectinvoked Bduring defined in bar()program termination } |
Compliant Solution
Compliant code must prevent exceptions from escaping during program startup and termination. A solution is to avoid defining at namespace scope objects whose constructors may throw, in addition to preventing exceptions from being thrown from destructors as outlined in Thus, it is important to prevent constructors of objects with static storage duration to throw exceptions. See also ERR33-CPP. Destructors must not throw exceptions.
Code Block | ||
---|---|---|
| ||
static const char global[] = "..."; void f() { static const struct LocalClass { // ... ~LocalClass() throw() { if (error_detected) { try { std::clog << "Runtime error: ...\n"; } catch(...) { // attempt to log error by other means } } } local_static; } int main() try { f(); } catch(...) { // handle exceptions thrown during the call to // f() and any other statements in the try block // above } |
References
Wiki Markup |
---|
\[[Sutter 00|AA. C++ References#Sutter 00]\] Sutter, Herb. Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions. |