C++ Destruction Order of Automatic Variables

In C++, the lifetime management of local automatic variables is strictly deterministic and forms the foundation of the Resource Acquisition Is Initialization (RAII) pattern. The C++ standard explicitly guarantees that local automatic variables are destroyed in the exact reverse order of their construction within their respective scopes. This article details the mechanics of this Last-In, First-Out (LIFO) destruction rule, how it functions across block exits, exceptions, arrays, and conditional control flows.

The Core Rule: Last-In, First-Out (LIFO)

The fundamental guarantee provided by the ISO C++ standard is that automatic objects declared within a given block scope are destroyed in reverse order of the completion of their construction.

If variable A is constructed before variable B in the same scope, B is guaranteed to be destroyed before A. This design ensures safety when objects hold dependencies on one another; if B relies on resources managed by A, B will cleanly shut down before A releases those underlying resources.

Scope Termination and Control Flow

Destruction occurs automatically when execution leaves the block in which the variables were declared. The C++ standard guarantees that this reverse-order destruction applies regardless of how the block is exited, including:

  • Reaching the closing brace (}) of the compound statement.
  • Executing a return statement.
  • Executing transfer-of-control statements such as break, continue, or goto.
  • Leaving the block due to an exception (known as stack unwinding).

In all cases, every fully constructed automatic variable in the scope being exited will have its destructor invoked before control passes out of that scope.

Loop Scopes

Variables declared inside the body of a loop (for, while, or do-while) are tied to the scope of each iteration. They are constructed upon declaration and destroyed in reverse order at the end of that specific iteration. They do not persist across iterations.

For variables declared within a for loop header (e.g., for (int i = 0; ...)), their lifetime spans the entire duration of the loop, and they are destroyed only after the final iteration completes and loop-body objects have already been destroyed.

Array Elements

When an array of automatic objects is declared, the elements are constructed in order of increasing subscript (0, 1, 2, ...). The standard mandates that their destruction must occur in the exact reverse order, from the highest index down to zero (... 2, 1, 0), before the scope containing the array is terminated.

Behavior During Exceptions

If an unhandled exception is thrown, the runtime initiates stack unwinding. During unwinding, the runtime identifies all automatic objects in scopes that are being exited and destroys them in reverse order of their construction.

If an exception occurs during the construction of a specific object, that object’s destructor will not be called because its construction never completed. However, any sub-objects, base classes, or previously declared local variables that were already fully constructed will be destroyed in reverse order of their construction.