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
returnstatement. - Executing transfer-of-control statements such as
break,continue, orgoto. - 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.