156 lines
6.0 KiB
Markdown
156 lines
6.0 KiB
Markdown
[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*]
|