Understanding the Issue
Throwing exceptions from destructors introduces a dilemma: what to do when an exception is already in flight? Overwriting the existing exception or nesting the new exception within the existing one are potential solutions, but it was decided that terminating with std::terminate would be the standard approach.
Consideration of Nested Exceptions
C 11 introduced the std::nested_exception feature, which could potentially address the issue by nesting the old exception within the new one. However, this idea was not implemented.
Reasons for Non-Implementation
One reason for not using nested exceptions in this context is the fact that std::nested_exception has very limited usage, with only one known practical application: creating fully-annotated call stacks.
This example demonstrates how nesting exceptions provides a convenient way to add context and pinpoint errors during debugging:
<code class="cpp">#include <iostream> #include <sstream> #include <exception> void rethrow(const std::string& context, ...) { std::ostringstream ss; ss << context; auto sep = " : "; (void) ((ss << sep << args), sep = ", ", 0)...); try { std::rethrow_exception(std::current_exception()); } catch(const std::invalid_argument& e) { std::throw_with_nested(std::invalid_argument(ss.str())); } catch(const std::logic_error& e) { std::throw_with_nested(std::logic_error(ss.str())); } catch(...) { std::throw_with_nested(std::runtime_error(ss.str())); } } int main() { try { outer("xyz"); outer("abcd"); } catch(std::exception& e) { print_exception(e); } return 0; } void print_exception(const std::exception& e, std::size_t depth = 0) { std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n'; try { std::rethrow_if_nested(e); } catch (const std::exception& nested) { print_exception(nested, depth + 1); } }</code>
Expected Output:
exception: outer : abcd exception: inner : abcdabcd exception: really_inner exception: too long
The above example showcases the nesting of exceptions and demonstrates how this technique aids in tracing errors and understanding call stacks.
Despite the utility of nested exceptions in this specific scenario, the decision not to use them in the context of destructor exceptions was likely made due to the ease and reliability of terminating with std::terminate.
The above is the detailed content of Why doesn\'t C use nested exceptions to handle exceptions thrown from destructors?. For more information, please follow other related articles on the PHP Chinese website!