...
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.
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 {
// ...
~LocalClass() { if (error_detected) throw std::runtime_error("..."); }
} local_static;
}
int main()
try {
f();
// other executable statements
}
catch(...) {
// handle exceptions thrown during the call to
// f() and any other statements in the try block
// above
// IMPORTANT: will not catch exceptions thrown
// from the constructor of global or those from
// the destructor of local_static defined in f()
// and invoked during 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 VOID 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
[Sutter 00] Sutter, Herb. Exceptional C++: 47 Engineering Puzzles, Programming Problems, and Solutions.