I'm testing how throwing when doing stack unwinding calls std::terminate
by having the copy constructor of the class that is used to throw, throwing.
Per C++14 N4296 - §15.1.3:
Throwing an exception copy-initializes (8.5, 12.8) a temporary object, called the exception object. The temporary is an lvalue and is used to initialize the variable declared in the matching handler (15.3).
class X
{
public:
X() = default;
X(const X&)
{
throw std::runtime_error{"X copy constructor"};
}
};
int main()
{
try
{
throw X{};
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl; // this line gets executed, does not terminate
}
catch(const X& other)
{
std::cout << "X exception" << std::endl;
}
}
How come the above code doesn't call std::terminate
? It is my understanding of the above code that the throw X{}
inside the try
, starts the stack winding and then the copy constructor gets called to call the handler, but the copy constructor throws as well. As a note if change the copy constructor's throw expression for throw X{}
then it terminates.