C++ standard says ([except.handle]/9):
If no matching handler is found, the function std::terminate() is called; whether or not the stack is unwound before this call to std::terminate() is implementation-defined
For example, behavior of code below (will it print S::~S() or not) is implementation defined:
struct S {
S() { std::cout << "S::S()" << std::endl; }
~S() { std::cout << "S::~S()" << std::endl; }
};
int main() {
S s;
throw std::runtime_error("exception");
}
I would like to know in-depth: why is it implementation defined? Why a context cannot be unwinded up to its entry before std::terminate() is called if an exception is uncaught (which is similar to try{ ... } catch(...) { throw; } in the top-level function)? At a glance, such behavior is much clearer and safer in consistence with RAII.