[except.ctor]

# 14 Exception handling [[except]](./#except)

## 14.3 Stack unwinding [except.ctor]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L386)

As control passes from the point where an exception is thrown
to a handler,
objects are destroyed by a process,
specified in this subclause, called [*stack unwinding*](#def:stack_unwinding "14.3 Stack unwinding [except.ctor]")[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L393)

Each object with automatic storage duration is destroyed if it has been
constructed, but not yet destroyed,
since the try block was entered[.](#2.sentence-1)

If an exception is thrown during the destruction of temporaries or
local variables for a return statement ([[stmt.return]](stmt.return "8.8.4 The return statement")),
the destructor for the returned object (if any) is also invoked[.](#2.sentence-2)

The objects are destroyed in the reverse order of the completion
of their construction[.](#2.sentence-3)

[*Example [1](#example-1)*: struct A { };

struct Y { ~Y() noexcept(false) { throw 0; } };

A f() {try { A a;
 Y y;
 A b; return {}; // #1} catch (...) {}return {}; // #2}

At #1, the returned object of type A is constructed[.](#2.sentence-4)

Then, the local variable b is destroyed ([[stmt.jump]](stmt.jump "8.8 Jump statements"))[.](#2.sentence-5)

Next, the local variable y is destroyed,
causing stack unwinding,
resulting in the destruction of the returned object,
followed by the destruction of the local variable a[.](#2.sentence-6)

Finally, the returned object is constructed again at #2[.](#2.sentence-7)

â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L428)

If the initialization of an object
other than by delegating constructor
is terminated by an exception,
the destructor is invoked for
each of the object's subobjects
that were known to be initialized by the object's initialization and
whose initialization has completed ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#3.sentence-1)

[*Note [1](#note-1)*:

If such an object has a reference member
that extends the lifetime of a temporary object,
this ends the lifetime of the reference member,
so the lifetime of the temporary object is effectively not extended[.](#3.sentence-2)

â *end note*]

A subobject is [*known to be initialized*](#def:known_to_be_initialized "14.3 Stack unwinding [except.ctor]") if it is not an anonymous union member and
its initialization is specified

- [(3.1)](#3.1)

in [[class.base.init]](class.base.init "11.9.3 Initializing bases and members") for initialization by constructor,

- [(3.2)](#3.2)

in [[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors") for initialization by defaulted copy/move constructor,

- [(3.3)](#3.3)

in [[class.inhctor.init]](class.inhctor.init "11.9.4 Initialization by inherited constructor") for initialization by inherited constructor,

- [(3.4)](#3.4)

in [[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates") for aggregate initialization,

- [(3.5)](#3.5)

in [[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures") for the initialization of
the closure object when evaluating a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"),

- [(3.6)](#3.6)

in [[dcl.init.general]](dcl.init.general "9.5.1 General") for
default-initialization, value-initialization, or direct-initialization
of an array[.](#3.sentence-3)

[*Note [2](#note-2)*:

This includes virtual base class subobjects
if the initialization
is for a complete object, and
can include variant members
that were nominated explicitly by
a [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") or [*designated-initializer-clause*](dcl.init.general#nt:designated-initializer-clause "9.5.1 General [dcl.init.general]") or
that have a default member initializer[.](#3.sentence-4)

â *end note*]

If the destructor of an object is terminated by an exception,
each destructor invocation
that would be performed after executing the body of the destructor ([[class.dtor]](class.dtor "11.4.7 Destructors")) and
that has not yet begun execution
is performed[.](#3.sentence-5)

[*Note [3](#note-3)*:

This includes virtual base class subobjects if
the destructor was invoked for a complete object[.](#3.sentence-6)

â *end note*]

The subobjects are destroyed in the reverse order of the completion of
their construction[.](#3.sentence-7)

Such destruction is sequenced before entering a
handler of the [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") of the constructor or destructor,
if any[.](#3.sentence-8)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L480)

If the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1 General [dcl.fct.def.general]") of a delegating constructor
for an object exits via
an exception, the object's destructor is invoked[.](#4.sentence-1)

Such destruction is sequenced before entering a handler of the[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") of a delegating constructor for that object, if any[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L489)

[*Note [4](#note-4)*:

If the object was allocated by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") ([[expr.new]](expr.new "7.6.2.8 New")),
the matching [deallocation function](basic.stc.dynamic.deallocation "6.8.6.5.3 Deallocation functions [basic.stc.dynamic.deallocation]"),
if any, is called to free the storage occupied by the object[.](#5.sentence-1)

â *end note*]
