Init
This commit is contained in:
155
cppdraft/except/ctor.md
Normal file
155
cppdraft/except/ctor.md
Normal file
@@ -0,0 +1,155 @@
|
||||
[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*]
|
||||
Reference in New Issue
Block a user