Are destructors called after a throw in C++?

C++Exception HandlingTry CatchRaii

C++ Problem Overview


I ran a sample program and indeed destructors for stack-allocated objects are called, but is this guaranteed by the standard?

C++ Solutions


Solution 1 - C++

Yes, it is guaranteed (provided the exception is caught), down to the order in which the destructors are invoked:

> C++11 15.2 Constructors and destructors [except.ctor]

>1 As control passes from a throw-expression to a handler, destructors are invoked for all > automatic objects constructed since the try block was entered. The > automatic objects are destroyed in the reverse order of the completion > of their construction.

Furthermore, if the exception is thrown during object construction, the subobjects of the partially-constructed object are guaranteed to be correctly destroyed:

> 2 An object of any storage duration whose initialization or > destruction is terminated by an exception will have destructors > executed for all of its fully constructed subobjects (excluding the > variant members of a union-like class), that is, for subobjects for > which the principal constructor (12.6.2) has completed execution and > the destructor has not yet begun execution. Similarly, if the > non-delegating constructor for an object has completed execution and a > delegating constructor for that object exits with an exception, the > object’s destructor will be invoked. If the object was allocated in a > new-expression, the matching deallocation function (3.7.4.2, 5.3.4, > 12.5), if any, is called to free the storage occupied by the object.

This whole process is known as "stack unwinding":

> 3 The process of calling destructors for automatic objects constructed > on the path from a try block to a throw-expression is called “stack > unwinding.” If a destructor called during stack unwinding exits with > an exception, std::terminate is called (15.5.1).

Stack unwinding forms the basis of the widely-used technique called Resource Acquisition Is Initialization (RAII).

Note that stack unwinding is not necessarily done if the exception is not caught. In this case it's up to the implementation whether stack unwinding is done. But whether stack unwinding is done or not, in this case you're guaranteed a final call to std::terminate.

> C++11 15.5.1 The std::terminate() function [except.terminate]

>2 … In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called.

Solution 2 - C++

Yes, destructors are guaranteed to be called on stack unwinding, including unwinding due to exception being thrown. There are only few tricks with exceptions that you have to remember:

  • Destructor of the class is not called if exception is thrown in its constructor.
  • Exception is automatically re-thrown if caught in construction initialization list catch block.

Solution 3 - C++

If a throw is caught then normally cpp operations continue. This include destructors and stack popping. However if the exception is not caught, stack popping is not guaranteed.

Also a bare throw or empty throw cannot be caught by my mobile compiler.

example:

#include <Jav/report.h>

int main()
{
 try { throw; }
 catch(...) { rep("I bet this is not caught"); }
 }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuchian GrigoreView Question on Stackoverflow
Solution 1 - C++NPEView Answer on Stackoverflow
Solution 2 - C++user405725View Answer on Stackoverflow
Solution 3 - C++user9599745View Answer on Stackoverflow