Skip to content

Commit 42d33f1

Browse files
committed
[except.throw][except.ctor] Move to [basic.exec]
1 parent 494fd23 commit 42d33f1

File tree

2 files changed

+306
-308
lines changed

2 files changed

+306
-308
lines changed

source/basic.tex

+306
Original file line numberDiff line numberDiff line change
@@ -6760,6 +6760,312 @@
67606760
\indextext{atomic!operation|)}%
67616761
\indextext{threads!multiple|)}
67626762

6763+
\rSec2[except.throw]{Throwing an exception}%
6764+
\indextext{exception handling!throwing}%
6765+
\indextext{throwing|see{exception handling, throwing}}
6766+
6767+
\pnum
6768+
Throwing an exception transfers control to a handler.
6769+
\begin{note}
6770+
An exception can be thrown from one of the following contexts:
6771+
\grammarterm{throw-expression}{s}\iref{expr.throw},
6772+
allocation functions\iref{basic.stc.dynamic.allocation},
6773+
\keyword{dynamic_cast}\iref{expr.dynamic.cast},
6774+
\keyword{typeid}\iref{expr.typeid},
6775+
\grammarterm{new-expression}{s}\iref{expr.new}, and standard library
6776+
functions\iref{structure.specifications}.
6777+
\end{note}
6778+
An object is passed and the type of that object determines which handlers
6779+
can catch it.
6780+
\begin{example}
6781+
\begin{codeblock}
6782+
throw "Help!";
6783+
\end{codeblock}
6784+
can be caught by a
6785+
\grammarterm{handler}
6786+
of
6787+
\keyword{const}
6788+
\tcode{\keyword{char}*}
6789+
type:
6790+
\begin{codeblock}
6791+
try {
6792+
// ...
6793+
} catch(const char* p) {
6794+
// handle character string exceptions here
6795+
}
6796+
\end{codeblock}
6797+
and
6798+
\begin{codeblock}
6799+
class Overflow {
6800+
public:
6801+
Overflow(char,double,double);
6802+
};
6803+
6804+
void f(double x) {
6805+
throw Overflow('+',x,3.45e107);
6806+
}
6807+
\end{codeblock}
6808+
can be caught by a handler for exceptions of type
6809+
\tcode{Overflow}:
6810+
\begin{codeblock}
6811+
try {
6812+
f(1.2);
6813+
} catch(Overflow& oo) {
6814+
// handle exceptions of type \tcode{Overflow} here
6815+
}
6816+
\end{codeblock}
6817+
\end{example}
6818+
6819+
\pnum
6820+
\indextext{exception handling!throwing}%
6821+
\indextext{exception handling!handler}%
6822+
\indextext{exception handling!nearest handler}%
6823+
When an exception is thrown, control is transferred to the nearest handler with
6824+
a matching type\iref{except.handle}; ``nearest'' means the handler
6825+
for which the
6826+
\grammarterm{compound-statement} or
6827+
\grammarterm{ctor-initializer}
6828+
following the
6829+
\keyword{try}
6830+
keyword was most recently entered by the thread of control and not yet exited.
6831+
6832+
\pnum
6833+
Throwing an exception
6834+
initializes an object with dynamic storage duration,
6835+
called the
6836+
\defnx{exception object}{exception handling!exception object}.
6837+
If the type of the exception object would be
6838+
an incomplete type\iref{basic.types.general},
6839+
an abstract class type\iref{class.abstract},
6840+
or a pointer to an incomplete type other than
6841+
\cv{}~\keyword{void}\iref{basic.compound},
6842+
the program is ill-formed.
6843+
6844+
\pnum
6845+
\indextext{exception handling!memory}%
6846+
\indextext{exception handling!rethrowing}%
6847+
\indextext{exception handling!exception object}%
6848+
The memory for the exception object is
6849+
allocated in an unspecified way, except as noted in~\ref{basic.stc.dynamic.allocation}.
6850+
If a handler exits by rethrowing, control is passed to another handler for
6851+
the same exception object.
6852+
The points of potential destruction for the exception object are:
6853+
\begin{itemize}
6854+
\item
6855+
when an active handler for the exception exits by
6856+
any means other than
6857+
rethrowing,
6858+
immediately after the destruction of the object (if any)
6859+
declared in the \grammarterm{exception-declaration} in the handler;
6860+
6861+
\item
6862+
when an object of type \tcode{std::exception_ptr}\iref{propagation}
6863+
that refers to the exception object is destroyed,
6864+
before the destructor of \tcode{std::exception_ptr} returns.
6865+
\end{itemize}
6866+
6867+
Among all points of potential destruction for the exception object,
6868+
there is an unspecified last one
6869+
where the exception object is destroyed.
6870+
All other points happen before that last one\iref{intro.races}.
6871+
\begin{note}
6872+
No other thread synchronization is implied in exception handling.
6873+
\end{note}
6874+
The implementation may then
6875+
deallocate the memory for the exception object; any such deallocation
6876+
is done in an unspecified way.
6877+
\begin{note}
6878+
A thrown exception does not
6879+
propagate to other threads unless caught, stored, and rethrown using
6880+
appropriate library functions; see~\ref{propagation} and~\ref{futures}.
6881+
\end{note}
6882+
6883+
\pnum
6884+
\indextext{exception handling!exception object!constructor}%
6885+
\indextext{exception handling!exception object!destructor}%
6886+
Let \tcode{T} denote the type of the exception object.
6887+
Copy-initialization of an object of type \tcode{T} from
6888+
an lvalue of type \tcode{const T} in a context unrelated to \tcode{T}
6889+
shall be well-formed.
6890+
If \tcode{T} is a class type,
6891+
the selected constructor is odr-used\iref{basic.def.odr} and
6892+
the destructor of \tcode{T} is potentially invoked\iref{class.dtor}.
6893+
6894+
\pnum
6895+
An exception is considered uncaught
6896+
after completing the initialization of the exception object
6897+
until completing the activation of a handler for the exception\iref{except.handle}.
6898+
\begin{note}
6899+
As a consequence, an exception is considered uncaught
6900+
during any stack unwinding resulting from it being thrown.
6901+
\end{note}
6902+
6903+
\pnum
6904+
\indextext{exception handling!rethrow}%
6905+
\indextext{rethrow|see{exception handling, rethrow}}%
6906+
An exception is considered caught when a handler for that exception
6907+
becomes active\iref{except.handle}.
6908+
\begin{note}
6909+
An exception can have active handlers and still be considered uncaught if
6910+
it is rethrown.
6911+
\end{note}
6912+
6913+
\pnum
6914+
\indexlibraryglobal{uncaught_exceptions}%
6915+
If an exception is rethrown\iref{expr.throw,propagation},
6916+
it is considered uncaught from the point of rethrow
6917+
until the rethrown exception is caught.
6918+
\begin{note}
6919+
The function \tcode{std::uncaught_exceptions}\iref{uncaught.exceptions}
6920+
returns the number of uncaught exceptions in the current thread.
6921+
\end{note}
6922+
6923+
\pnum
6924+
\indextext{exception handling!terminate called@\tcode{terminate} called}%
6925+
\indextext{\idxcode{terminate}!called}%
6926+
If the exception handling mechanism
6927+
handling an uncaught exception
6928+
directly invokes a function that exits via an
6929+
exception, the function \tcode{std::terminate} is invoked\iref{except.terminate}.
6930+
\begin{example}
6931+
\begin{codeblock}
6932+
struct C {
6933+
C() { }
6934+
C(const C&) {
6935+
if (std::uncaught_exceptions()) {
6936+
throw 0; // throw during copy to handler's \grammarterm{exception-declaration} object\iref{except.handle}
6937+
}
6938+
}
6939+
};
6940+
6941+
int main() {
6942+
try {
6943+
throw C(); // calls \tcode{std::terminate} if construction of the handler's
6944+
// \grammarterm{exception-declaration} object is not elided\iref{class.copy.elision}
6945+
} catch(C) { }
6946+
}
6947+
\end{codeblock}
6948+
\end{example}
6949+
\begin{note}
6950+
If a destructor directly invoked by stack unwinding exits via an exception,
6951+
\tcode{std::terminate} is invoked.
6952+
\end{note}
6953+
6954+
\rSec2[except.ctor]{Stack unwinding}%
6955+
\indextext{exception handling!constructors and destructors}%
6956+
\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}%
6957+
\indextext{destructor!exception handling|see{exception handling, constructors and destructors}}
6958+
6959+
\pnum
6960+
\indextext{unwinding!stack}%
6961+
As control passes from the point where an exception is thrown
6962+
to a handler,
6963+
objects are destroyed by a process,
6964+
specified in this subclause, called \defn{stack unwinding}.
6965+
6966+
\pnum
6967+
Each object with automatic storage duration is destroyed if it has been
6968+
constructed, but not yet destroyed,
6969+
since the try block was entered.
6970+
If an exception is thrown during the destruction of temporaries or
6971+
local variables for a \keyword{return} statement\iref{stmt.return},
6972+
the destructor for the returned object (if any) is also invoked.
6973+
The objects are destroyed in the reverse order of the completion
6974+
of their construction.
6975+
\begin{example}
6976+
\begin{codeblock}
6977+
struct A { };
6978+
6979+
struct Y { ~Y() noexcept(false) { throw 0; } };
6980+
6981+
A f() {
6982+
try {
6983+
A a;
6984+
Y y;
6985+
A b;
6986+
return {}; // \#1
6987+
} catch (...) {
6988+
}
6989+
return {}; // \#2
6990+
}
6991+
\end{codeblock}
6992+
At \#1, the returned object of type \tcode{A} is constructed.
6993+
Then, the local variable \tcode{b} is destroyed\iref{stmt.jump}.
6994+
Next, the local variable \tcode{y} is destroyed,
6995+
causing stack unwinding,
6996+
resulting in the destruction of the returned object,
6997+
followed by the destruction of the local variable \tcode{a}.
6998+
Finally, the returned object is constructed again at \#2.
6999+
\end{example}
7000+
7001+
\pnum
7002+
If the initialization of an object
7003+
other than by delegating constructor
7004+
is terminated by an exception,
7005+
the destructor is invoked for
7006+
each of the object's subobjects
7007+
that were known to be initialized by the object's initialization and
7008+
whose initialization has completed\iref{dcl.init}.
7009+
\begin{note}
7010+
If such an object has a reference member
7011+
that extends the lifetime of a temporary object,
7012+
this ends the lifetime of the reference member,
7013+
so the lifetime of the temporary object is effectively not extended.
7014+
\end{note}
7015+
\indextext{subobject!initialized, known to be}%
7016+
A subobject is \defn{known to be initialized}
7017+
if it is not an anonymous union member and
7018+
its initialization is specified
7019+
\begin{itemize}
7020+
\item in \ref{class.base.init} for initialization by constructor,
7021+
\item in \ref{class.copy.ctor} for initialization by defaulted copy/move constructor,
7022+
\item in \ref{class.inhctor.init} for initialization by inherited constructor,
7023+
\item in \ref{dcl.init.aggr} for aggregate initialization,
7024+
\item in \ref{expr.prim.lambda.capture} for the initialization of
7025+
the closure object when evaluating a \grammarterm{lambda-expression},
7026+
\item in \ref{dcl.init.general} for
7027+
default-initialization, value-initialization, or direct-initialization
7028+
of an array.
7029+
\end{itemize}
7030+
\begin{note}
7031+
This includes virtual base class subobjects
7032+
if the initialization
7033+
is for a complete object, and
7034+
can include variant members
7035+
that were nominated explicitly by
7036+
a \grammarterm{mem-initializer} or \grammarterm{designated-initializer-clause} or
7037+
that have a default member initializer.
7038+
\end{note}
7039+
If the destructor of an object is terminated by an exception,
7040+
each destructor invocation
7041+
that would be performed after executing the body of the destructor\iref{class.dtor} and
7042+
that has not yet begun execution
7043+
is performed.
7044+
\begin{note}
7045+
This includes virtual base class subobjects if
7046+
the destructor was invoked for a complete object.
7047+
\end{note}
7048+
The subobjects are destroyed in the reverse order of the completion of
7049+
their construction. Such destruction is sequenced before entering a
7050+
handler of the \grammarterm{function-try-block} of the constructor or destructor,
7051+
if any.
7052+
7053+
\pnum
7054+
If the \grammarterm{compound-statement}
7055+
of the \grammarterm{function-body}
7056+
of a delegating constructor
7057+
for an object exits via
7058+
an exception, the object's destructor is invoked.
7059+
Such destruction is sequenced before entering a handler of the
7060+
\grammarterm{function-try-block} of a delegating constructor for that object, if any.
7061+
7062+
\pnum
7063+
\begin{note}
7064+
If the object was allocated by a \grammarterm{new-expression}\iref{expr.new},
7065+
the matching deallocation function\iref{basic.stc.dynamic.deallocation},
7066+
if any, is called to free the storage occupied by the object.
7067+
\end{note}
7068+
67637069
\rSec2[basic.start]{Start and termination}
67647070

67657071
\rSec3[basic.start.main]{\tcode{main} function}

0 commit comments

Comments
 (0)