Uncaught Exceptions in C++

What does actually happen, if an exception is thrown somewhere in the middle of a C++ program, but there is no try-catch clause which handles it? The program gets terminated. That is fine in general, but what happens to all objects which need to be properly destructed?

Let’s try it out:

This program instanciates three Foo objects: A global one, a static global one, and a local stack instance. Foo’s destructor just emits a message which tells which one of the three instances was just destructed.

(I wrapped the throw clause into a conditional which the compiler cannot optimize away, as it cannot predict with how many parameters the executable will be called.)

In the ideal case, the compiler should emit code which unrolls the stack as soon as the exception is thrown, destructs all objects which are in flight and then terminates the program:

Ooops, unfortunately, this is not the case: If those Foo objects held any unflushed buffers, they’d be gone now!

Wrapping the exception into a try-catch clause fixes this behaviour.

The output looks much better now. All objects are properly destructed:

The C++11 standard says the following in section 15.3.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 (15.5.1).

“Whether or not the stack is unwound” is the crunch point here: It is not unwound in our case.

This becomes especially important In C++14, where it is possible to throw exceptions from within constexpr functions. This can be used as an approach which provides assert behaviour at compile time and at run time (whereas static_assert does not help at run time).