Skip to content

Commit 55d85db

Browse files
committed
[except.pre] Clean-up pass to ensure consistency
1 parent f142ecc commit 55d85db

8 files changed

+487
-483
lines changed

source/basic.tex

+266-5
Original file line numberDiff line numberDiff line change
@@ -6760,7 +6760,14 @@
67606760
\indextext{atomic!operation|)}%
67616761
\indextext{threads!multiple|)}
67626762

6763-
\rSec2[except.throw]{Throwing an exception}%
6763+
\rSec2[except.flow]{Exceptional control flow}
6764+
6765+
\rSec3[except.general]{General}
6766+
\pnum
6767+
In this Clause, ``before'' and ``after'' refer to the
6768+
``sequenced before'' relation\iref{intro.execution}.
6769+
6770+
\rSec3[except.throw]{Throwing an exception}%
67646771
\indextext{exception handling!throwing}%
67656772
\indextext{throwing|see{exception handling, throwing}}
67666773

@@ -6951,7 +6958,7 @@
69516958
\tcode{std::terminate} is invoked.
69526959
\end{note}
69536960

6954-
\rSec2[except.ctor]{Stack unwinding}%
6961+
\rSec3[except.ctor]{Stack unwinding}%
69556962
\indextext{exception handling!constructors and destructors}%
69566963
\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}%
69576964
\indextext{destructor!exception handling|see{exception handling, constructors and destructors}}
@@ -7066,6 +7073,260 @@
70667073
if any, is called to free the storage occupied by the object.
70677074
\end{note}
70687075

7076+
\rSec3[except.handle]{Handling an exception}
7077+
\indextext{exception handling!handler|(}%
7078+
7079+
\pnum
7080+
The
7081+
\grammarterm{exception-declaration}
7082+
in a
7083+
\grammarterm{handler}
7084+
describes the type(s) of exceptions that can cause
7085+
that
7086+
\grammarterm{handler}
7087+
to be entered.
7088+
\indextext{exception handling!handler!incomplete type in}%
7089+
\indextext{exception handling!handler!rvalue reference in}%
7090+
\indextext{exception handling!handler!array in}%
7091+
\indextext{exception handling!handler!pointer to function in}%
7092+
The
7093+
\grammarterm{exception-declaration}
7094+
shall not denote an incomplete type, an abstract class type, or an rvalue reference type.
7095+
The
7096+
\grammarterm{exception-declaration}
7097+
shall not denote a pointer or reference to an
7098+
incomplete type, other than ``pointer to \cv{}~\keyword{void}''.
7099+
7100+
\pnum
7101+
A handler of type
7102+
\indextext{array!handler of type}%
7103+
``array of \tcode{T}'' or
7104+
\indextext{function!handler of type}%
7105+
function type \tcode{T}
7106+
is adjusted to be of type
7107+
``pointer to \tcode{T}''.
7108+
7109+
\pnum
7110+
\indextext{exception handling!handler!match|(}%
7111+
A
7112+
\grammarterm{handler}
7113+
is a match for
7114+
an exception object
7115+
of type
7116+
\tcode{E}
7117+
if
7118+
\begin{itemize}
7119+
\item%
7120+
The \grammarterm{handler} is of type \cv{}~\tcode{T} or
7121+
\cv{}~\tcode{T\&} and
7122+
\tcode{E} and \tcode{T}
7123+
are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or
7124+
\item%
7125+
the \grammarterm{handler} is of type \cv{}~\tcode{T} or
7126+
\cv{}~\tcode{T\&} and
7127+
\tcode{T} is an unambiguous public base class of \tcode{E}, or
7128+
\item%
7129+
the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&}
7130+
where \tcode{T} is a pointer or pointer-to-member type and
7131+
\tcode{E} is a pointer or pointer-to-member type
7132+
that can be converted to \tcode{T} by one or more of
7133+
\begin{itemize}
7134+
7135+
\item%
7136+
a standard pointer conversion\iref{conv.ptr} not involving conversions
7137+
to pointers to private or protected or ambiguous classes
7138+
\item%
7139+
a function pointer conversion\iref{conv.fctptr}
7140+
\item%
7141+
a qualification conversion\iref{conv.qual}, or
7142+
7143+
\end{itemize}
7144+
7145+
\item
7146+
the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}.
7147+
7148+
\end{itemize}
7149+
7150+
\begin{note}
7151+
A
7152+
\grammarterm{throw-expression}
7153+
whose operand is an integer literal with value zero does not match a handler of
7154+
pointer or pointer-to-member type.
7155+
A handler of reference to array or function type
7156+
is never a match for any exception object\iref{expr.throw}.
7157+
\end{note}
7158+
7159+
\begin{example}
7160+
\begin{codeblock}
7161+
class Matherr { @\commentellip@ virtual void vf(); };
7162+
class Overflow: public Matherr { @\commentellip@ };
7163+
class Underflow: public Matherr { @\commentellip@ };
7164+
class Zerodivide: public Matherr { @\commentellip@ };
7165+
7166+
void f() {
7167+
try {
7168+
g();
7169+
} catch (Overflow oo) {
7170+
// ...
7171+
} catch (Matherr mm) {
7172+
// ...
7173+
}
7174+
}
7175+
\end{codeblock}
7176+
Here, the
7177+
\tcode{Overflow}
7178+
handler will catch exceptions of type
7179+
\tcode{Overflow}
7180+
and the
7181+
\tcode{Matherr}
7182+
handler will catch exceptions of type
7183+
\tcode{Matherr}
7184+
and of all types publicly derived from
7185+
\tcode{Matherr}
7186+
including exceptions of type
7187+
\tcode{Underflow}
7188+
and
7189+
\tcode{Zerodivide}.
7190+
\end{example}
7191+
7192+
\pnum
7193+
The handlers for a try block are tried in order of appearance.
7194+
\begin{note}
7195+
This makes it possible to write handlers that can never be
7196+
executed, for example by placing a handler for a final derived class after
7197+
a handler for a corresponding unambiguous public base class.
7198+
\end{note}
7199+
7200+
\pnum
7201+
A
7202+
\tcode{...}
7203+
in a handler's
7204+
\grammarterm{exception-declaration}
7205+
specifies a match for any exception.
7206+
If present, a
7207+
\tcode{...}
7208+
handler shall be the last handler for its try block.
7209+
7210+
\pnum
7211+
If no match is found among the handlers for a try block,
7212+
the search for a matching
7213+
handler continues in a dynamically surrounding try block
7214+
of the same thread.
7215+
7216+
\pnum
7217+
\indextext{exception handling!terminate called@\tcode{terminate} called}%
7218+
\indextext{\idxcode{terminate}!called}%
7219+
If the search for a handler
7220+
encounters the outermost block of a function with a
7221+
non-throwing exception specification,
7222+
the function \tcode{std::terminate}\iref{except.terminate} is invoked.
7223+
\begin{note}
7224+
An implementation is not permitted to reject an expression merely because, when
7225+
executed, it throws or might
7226+
throw an exception from a function with a non-throwing exception specification.
7227+
\end{note}
7228+
\begin{example}
7229+
\begin{codeblock}
7230+
extern void f(); // potentially-throwing
7231+
7232+
void g() noexcept {
7233+
f(); // valid, even if \tcode{f} throws
7234+
throw 42; // valid, effectively a call to \tcode{std::terminate}
7235+
}
7236+
\end{codeblock}
7237+
The call to
7238+
\tcode{f}
7239+
is well-formed despite the possibility for it to throw an exception.
7240+
\end{example}
7241+
7242+
\pnum
7243+
If no matching handler is found,
7244+
the function \tcode{std::terminate} is invoked;
7245+
whether or not the stack is unwound before this invocation of
7246+
\tcode{std::terminate} is
7247+
\impldef{whether stack is unwound before invoking the function \tcode{std::terminate}
7248+
when no matching handler is found}\iref{except.terminate}
7249+
7250+
\pnum
7251+
A handler is considered \defnx{active}{exception handling!handler!active} when
7252+
initialization is complete for the parameter (if any) of the catch clause.
7253+
\begin{note}
7254+
The stack will have been unwound at that point.
7255+
\end{note}
7256+
Also, an implicit handler is considered active when
7257+
the function \tcode{std::terminate}
7258+
is entered due to a throw. A handler is no longer considered active when the
7259+
catch clause exits.
7260+
7261+
\pnum
7262+
\indextext{currently handled exception|see{exception handling, currently handled exception}}%
7263+
The exception with the most recently activated handler that is
7264+
still active is called the
7265+
\defnx{currently handled exception}{exception handling!currently handled exception}.
7266+
7267+
\pnum
7268+
Referring to any non-static member or base class of an object
7269+
in the handler for a
7270+
\grammarterm{function-try-block}
7271+
of a constructor or destructor for that object results in undefined behavior.
7272+
7273+
\pnum
7274+
Exceptions thrown in destructors of objects with static storage duration or in
7275+
constructors of objects associated with non-block variables with static storage duration are not caught by a
7276+
\grammarterm{function-try-block}
7277+
on
7278+
the \tcode{main} function\iref{basic.start.main}.
7279+
Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a
7280+
\grammarterm{function-try-block}
7281+
on the initial function of the thread.
7282+
7283+
\pnum
7284+
If a \keyword{return} statement\iref{stmt.return} appears in a handler of the
7285+
\grammarterm{function-try-block}
7286+
of a
7287+
constructor, the program is ill-formed.
7288+
7289+
\pnum
7290+
The currently handled exception
7291+
is rethrown if control reaches the end of a handler of the
7292+
\grammarterm{function-try-block}
7293+
of a constructor or destructor.
7294+
Otherwise, flowing off the end of
7295+
the \grammarterm{compound-statement}
7296+
of a \grammarterm{handler}
7297+
of a \grammarterm{function-try-block}
7298+
is equivalent to flowing off the end of
7299+
the \grammarterm{compound-statement}
7300+
of that function (see \ref{stmt.return}).
7301+
7302+
\pnum
7303+
The variable declared by the \grammarterm{exception-declaration}, of type
7304+
\cv{}~\tcode{T} or \cv{}~\tcode{T\&}, is initialized from the exception object,
7305+
of type \tcode{E}, as follows:
7306+
\begin{itemize}
7307+
\item
7308+
if \tcode{T} is a base class of \tcode{E},
7309+
the variable is copy-initialized\iref{dcl.init}
7310+
from an lvalue of type \tcode{T} designating the corresponding base class subobject
7311+
of the exception object;
7312+
\item otherwise, the variable is copy-initialized\iref{dcl.init}
7313+
from an lvalue of type \tcode{E} designating the exception object.
7314+
\end{itemize}
7315+
7316+
The lifetime of the variable ends
7317+
when the handler exits, after the
7318+
destruction of any objects with automatic storage duration initialized
7319+
within the handler.
7320+
7321+
\pnum
7322+
When the handler declares an object,
7323+
any changes to that object will not affect the exception object.
7324+
When the handler declares a reference to an object,
7325+
any changes to the referenced object are changes to the
7326+
exception object and will have effect should that object be rethrown.%
7327+
\indextext{exception handling!handler!match|)}%
7328+
\indextext{exception handling!handler|)}
7329+
70697330
\rSec2[basic.start]{Start and termination}
70707331

70717332
\rSec3[basic.start.main]{\tcode{main} function}
@@ -7603,9 +7864,9 @@
76037864
\pnum
76047865
\indextext{\idxcode{terminate}}%
76057866
In the situation where no matching handler is found, it is
7606-
\impldef{stack unwinding before invocation of \tcode{std::terminate}}
7607-
whether or not the stack is unwound
7608-
before \tcode{std::terminate} is invoked.
7867+
\impldef{whether stack is unwound before invoking the function \tcode{std::terminate}
7868+
when no matching handler is found}
7869+
whether or not the stack is unwound before \tcode{std::terminate} is invoked.
76097870
In the situation where the search for a handler\iref{except.handle} encounters the
76107871
outermost block of a function
76117872
with a non-throwing exception specification\iref{except.spec}, it is

0 commit comments

Comments
 (0)