tmp/tmpmu7hy4cx/{from.md → to.md}
RENAMED
|
@@ -4,37 +4,34 @@ The predicate indicating whether a function cannot exit via an exception
|
|
| 4 |
is called the *exception specification* of the function. If the
|
| 5 |
predicate is false, the function has a *potentially-throwing exception
|
| 6 |
specification*, otherwise it has a *non-throwing exception
|
| 7 |
specification*. The exception specification is either defined
|
| 8 |
implicitly, or defined explicitly by using a *noexcept-specifier* as a
|
| 9 |
-
suffix of a function declarator
|
| 10 |
|
| 11 |
``` bnf
|
| 12 |
noexcept-specifier:
|
| 13 |
'noexcept' '(' constant-expression ')'
|
| 14 |
'noexcept'
|
| 15 |
-
'throw' '(' ')'
|
| 16 |
```
|
| 17 |
|
| 18 |
In a *noexcept-specifier*, the *constant-expression*, if supplied, shall
|
| 19 |
-
be a contextually converted constant expression of type `bool`
|
| 20 |
-
[[expr.const]]
|
| 21 |
of the function type in which the *noexcept-specifier* appears. A `(`
|
| 22 |
token that follows `noexcept` is part of the *noexcept-specifier* and
|
| 23 |
-
does not commence an initializer
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
*noexcept-specifier* `throw()` is deprecated ([[depr.except.spec]]),
|
| 27 |
-
and equivalent to the *noexcept-specifier* `noexcept(true)`.
|
| 28 |
|
| 29 |
If a declaration of a function does not have a *noexcept-specifier*, the
|
| 30 |
declaration has a potentially throwing exception specification unless it
|
| 31 |
is a destructor or a deallocation function or is defaulted on its first
|
| 32 |
-
declaration, in which cases the exception
|
| 33 |
below and no other declaration for that function shall have a
|
| 34 |
-
*noexcept-specifier*. In an explicit instantiation
|
| 35 |
-
|
| 36 |
*noexcept-specifier* is specified in an explicit instantiation
|
| 37 |
directive, the exception specification shall be the same as the
|
| 38 |
exception specification of all other declarations of that function. A
|
| 39 |
diagnostic is required only if the exception specifications are not the
|
| 40 |
same within a single translation unit.
|
|
@@ -53,11 +50,11 @@ struct B {
|
|
| 53 |
virtual void g();
|
| 54 |
virtual void h() noexcept = delete;
|
| 55 |
};
|
| 56 |
|
| 57 |
struct D: B {
|
| 58 |
-
void f(); //
|
| 59 |
void g() noexcept; // OK
|
| 60 |
void h() = delete; // OK
|
| 61 |
};
|
| 62 |
```
|
| 63 |
|
|
@@ -65,18 +62,19 @@ The declaration of `D::f` is ill-formed because it has a
|
|
| 65 |
potentially-throwing exception specification, whereas `B::f` has a
|
| 66 |
non-throwing exception specification.
|
| 67 |
|
| 68 |
— *end example*]
|
| 69 |
|
| 70 |
-
Whenever an exception is thrown and the search for a handler
|
| 71 |
-
[[except.handle]]
|
| 72 |
-
non-throwing exception specification, the function `std::terminate
|
| 73 |
-
called
|
| 74 |
|
| 75 |
-
[*Note 1*: An implementation
|
| 76 |
-
because, when executed, it throws or might throw an exception
|
| 77 |
-
function with a non-throwing exception
|
|
|
|
| 78 |
|
| 79 |
[*Example 2*:
|
| 80 |
|
| 81 |
``` cpp
|
| 82 |
extern void f(); // potentially-throwing
|
|
@@ -90,26 +88,26 @@ void g() noexcept {
|
|
| 90 |
The call to `f` is well-formed even though, when called, `f` might throw
|
| 91 |
an exception.
|
| 92 |
|
| 93 |
— *end example*]
|
| 94 |
|
| 95 |
-
An expression
|
| 96 |
|
| 97 |
-
-
|
| 98 |
-
|
| 99 |
potentially-throwing exception specification, or
|
| 100 |
-
-
|
| 101 |
allocation function in a *new-expression*, a constructor for a
|
| 102 |
-
function argument, or a destructor if
|
| 103 |
-
[[intro.execution]])
|
| 104 |
-
-
|
| 105 |
-
-
|
| 106 |
-
requires a runtime check
|
| 107 |
-
-
|
| 108 |
built-in unary `*` operator applied to a pointer to a polymorphic
|
| 109 |
-
class type
|
| 110 |
-
- any of the immediate subexpressions
|
| 111 |
potentially-throwing.
|
| 112 |
|
| 113 |
An implicitly-declared constructor for a class `X`, or a constructor
|
| 114 |
without a *noexcept-specifier* that is defaulted on its first
|
| 115 |
declaration, has a potentially-throwing exception specification if and
|
|
@@ -122,44 +120,51 @@ only if any of the following constructs is potentially-throwing:
|
|
| 122 |
expression, or,
|
| 123 |
- for a default constructor, a default member initializer.
|
| 124 |
|
| 125 |
[*Note 2*: Even though destructors for fully-constructed subobjects are
|
| 126 |
invoked when an exception is thrown during the execution of a
|
| 127 |
-
constructor
|
| 128 |
contribute to the exception specification of the constructor, because an
|
| 129 |
-
exception thrown from such a destructor would call
|
| 130 |
-
rather than escape the constructor ([[except.throw]],
|
| 131 |
[[except.terminate]]). — *end note*]
|
| 132 |
|
| 133 |
The exception specification for an implicitly-declared destructor, or a
|
| 134 |
destructor without a *noexcept-specifier*, is potentially-throwing if
|
| 135 |
and only if any of the destructors for any of its potentially
|
| 136 |
-
constructed
|
|
|
|
|
|
|
| 137 |
|
| 138 |
The exception specification for an implicitly-declared assignment
|
| 139 |
operator, or an assignment-operator without a *noexcept-specifier* that
|
| 140 |
is defaulted on its first declaration, is potentially-throwing if and
|
| 141 |
only if the invocation of any assignment operator in the implicit
|
| 142 |
definition is potentially-throwing.
|
| 143 |
|
| 144 |
-
A deallocation function
|
| 145 |
explicit *noexcept-specifier* has a non-throwing exception
|
| 146 |
specification.
|
| 147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
[*Example 3*:
|
| 149 |
|
| 150 |
``` cpp
|
| 151 |
struct A {
|
| 152 |
A(int = (A(5), 0)) noexcept;
|
| 153 |
A(const A&) noexcept;
|
| 154 |
A(A&&) noexcept;
|
| 155 |
~A();
|
| 156 |
};
|
| 157 |
struct B {
|
| 158 |
-
B()
|
| 159 |
B(const B&) = default; // implicit exception specification is noexcept(true)
|
| 160 |
-
B(B&&, int = (throw
|
| 161 |
~B() noexcept(false);
|
| 162 |
};
|
| 163 |
int n = 7;
|
| 164 |
struct D : public A, public B {
|
| 165 |
int * p = new int[n];
|
|
@@ -180,24 +185,23 @@ base class function has a non-throwing exception specification.
|
|
| 180 |
An exception specification is considered to be *needed* when:
|
| 181 |
|
| 182 |
- in an expression, the function is the unique lookup result or the
|
| 183 |
selected member of a set of overloaded functions ([[basic.lookup]],
|
| 184 |
[[over.match]], [[over.over]]);
|
| 185 |
-
- the function is odr-used
|
| 186 |
unevaluated operand, would be odr-used if the expression were
|
| 187 |
potentially-evaluated;
|
| 188 |
- the exception specification is compared to that of another declaration
|
| 189 |
(e.g., an explicit specialization or an overriding virtual function);
|
| 190 |
- the function is defined; or
|
| 191 |
-
- the exception specification is needed for a defaulted
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
against. — *end note*]
|
| 198 |
|
| 199 |
-
The exception specification of a defaulted
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
|
|
|
|
| 4 |
is called the *exception specification* of the function. If the
|
| 5 |
predicate is false, the function has a *potentially-throwing exception
|
| 6 |
specification*, otherwise it has a *non-throwing exception
|
| 7 |
specification*. The exception specification is either defined
|
| 8 |
implicitly, or defined explicitly by using a *noexcept-specifier* as a
|
| 9 |
+
suffix of a function declarator [[dcl.fct]].
|
| 10 |
|
| 11 |
``` bnf
|
| 12 |
noexcept-specifier:
|
| 13 |
'noexcept' '(' constant-expression ')'
|
| 14 |
'noexcept'
|
|
|
|
| 15 |
```
|
| 16 |
|
| 17 |
In a *noexcept-specifier*, the *constant-expression*, if supplied, shall
|
| 18 |
+
be a contextually converted constant expression of type `bool`
|
| 19 |
+
[[expr.const]]; that constant expression is the exception specification
|
| 20 |
of the function type in which the *noexcept-specifier* appears. A `(`
|
| 21 |
token that follows `noexcept` is part of the *noexcept-specifier* and
|
| 22 |
+
does not commence an initializer [[dcl.init]]. The *noexcept-specifier*
|
| 23 |
+
`noexcept` without a *constant-expression* is equivalent to the
|
| 24 |
+
*noexcept-specifier* `noexcept(true)`.
|
|
|
|
|
|
|
| 25 |
|
| 26 |
If a declaration of a function does not have a *noexcept-specifier*, the
|
| 27 |
declaration has a potentially throwing exception specification unless it
|
| 28 |
is a destructor or a deallocation function or is defaulted on its first
|
| 29 |
+
declaration, in which cases the exception specification is as specified
|
| 30 |
below and no other declaration for that function shall have a
|
| 31 |
+
*noexcept-specifier*. In an explicit instantiation [[temp.explicit]] a
|
| 32 |
+
*noexcept-specifier* may be specified, but is not required. If a
|
| 33 |
*noexcept-specifier* is specified in an explicit instantiation
|
| 34 |
directive, the exception specification shall be the same as the
|
| 35 |
exception specification of all other declarations of that function. A
|
| 36 |
diagnostic is required only if the exception specifications are not the
|
| 37 |
same within a single translation unit.
|
|
|
|
| 50 |
virtual void g();
|
| 51 |
virtual void h() noexcept = delete;
|
| 52 |
};
|
| 53 |
|
| 54 |
struct D: B {
|
| 55 |
+
void f(); // error
|
| 56 |
void g() noexcept; // OK
|
| 57 |
void h() = delete; // OK
|
| 58 |
};
|
| 59 |
```
|
| 60 |
|
|
|
|
| 62 |
potentially-throwing exception specification, whereas `B::f` has a
|
| 63 |
non-throwing exception specification.
|
| 64 |
|
| 65 |
— *end example*]
|
| 66 |
|
| 67 |
+
Whenever an exception is thrown and the search for a handler
|
| 68 |
+
[[except.handle]] encounters the outermost block of a function with a
|
| 69 |
+
non-throwing exception specification, the function `std::terminate` is
|
| 70 |
+
called [[except.terminate]].
|
| 71 |
|
| 72 |
+
[*Note 1*: An implementation is not permitted to reject an expression
|
| 73 |
+
merely because, when executed, it throws or might throw an exception
|
| 74 |
+
from a function with a non-throwing exception
|
| 75 |
+
specification. — *end note*]
|
| 76 |
|
| 77 |
[*Example 2*:
|
| 78 |
|
| 79 |
``` cpp
|
| 80 |
extern void f(); // potentially-throwing
|
|
|
|
| 88 |
The call to `f` is well-formed even though, when called, `f` might throw
|
| 89 |
an exception.
|
| 90 |
|
| 91 |
— *end example*]
|
| 92 |
|
| 93 |
+
An expression E is *potentially-throwing* if
|
| 94 |
|
| 95 |
+
- E is a function call [[expr.call]] whose *postfix-expression* has a
|
| 96 |
+
function type, or a pointer-to-function type, with a
|
| 97 |
potentially-throwing exception specification, or
|
| 98 |
+
- E implicitly invokes a function (such as an overloaded operator, an
|
| 99 |
allocation function in a *new-expression*, a constructor for a
|
| 100 |
+
function argument, or a destructor if E is a full-expression
|
| 101 |
+
[[intro.execution]]) that is potentially-throwing, or
|
| 102 |
+
- E is a *throw-expression* [[expr.throw]], or
|
| 103 |
+
- E is a `dynamic_cast` expression that casts to a reference type and
|
| 104 |
+
requires a runtime check [[expr.dynamic.cast]], or
|
| 105 |
+
- E is a `typeid` expression applied to a (possibly parenthesized)
|
| 106 |
built-in unary `*` operator applied to a pointer to a polymorphic
|
| 107 |
+
class type [[expr.typeid]], or
|
| 108 |
+
- any of the immediate subexpressions [[intro.execution]] of E is
|
| 109 |
potentially-throwing.
|
| 110 |
|
| 111 |
An implicitly-declared constructor for a class `X`, or a constructor
|
| 112 |
without a *noexcept-specifier* that is defaulted on its first
|
| 113 |
declaration, has a potentially-throwing exception specification if and
|
|
|
|
| 120 |
expression, or,
|
| 121 |
- for a default constructor, a default member initializer.
|
| 122 |
|
| 123 |
[*Note 2*: Even though destructors for fully-constructed subobjects are
|
| 124 |
invoked when an exception is thrown during the execution of a
|
| 125 |
+
constructor [[except.ctor]], their exception specifications do not
|
| 126 |
contribute to the exception specification of the constructor, because an
|
| 127 |
+
exception thrown from such a destructor would call the function
|
| 128 |
+
`std::terminate` rather than escape the constructor ([[except.throw]],
|
| 129 |
[[except.terminate]]). — *end note*]
|
| 130 |
|
| 131 |
The exception specification for an implicitly-declared destructor, or a
|
| 132 |
destructor without a *noexcept-specifier*, is potentially-throwing if
|
| 133 |
and only if any of the destructors for any of its potentially
|
| 134 |
+
constructed subobjects is potentially-throwing or the destructor is
|
| 135 |
+
virtual and the destructor of any virtual base class is
|
| 136 |
+
potentially-throwing.
|
| 137 |
|
| 138 |
The exception specification for an implicitly-declared assignment
|
| 139 |
operator, or an assignment-operator without a *noexcept-specifier* that
|
| 140 |
is defaulted on its first declaration, is potentially-throwing if and
|
| 141 |
only if the invocation of any assignment operator in the implicit
|
| 142 |
definition is potentially-throwing.
|
| 143 |
|
| 144 |
+
A deallocation function [[basic.stc.dynamic.deallocation]] with no
|
| 145 |
explicit *noexcept-specifier* has a non-throwing exception
|
| 146 |
specification.
|
| 147 |
|
| 148 |
+
The exception specification for a comparison operator function
|
| 149 |
+
[[over.binary]] without a *noexcept-specifier* that is defaulted on its
|
| 150 |
+
first declaration is potentially-throwing if and only if any expression
|
| 151 |
+
in the implicit definition is potentially-throwing.
|
| 152 |
+
|
| 153 |
[*Example 3*:
|
| 154 |
|
| 155 |
``` cpp
|
| 156 |
struct A {
|
| 157 |
A(int = (A(5), 0)) noexcept;
|
| 158 |
A(const A&) noexcept;
|
| 159 |
A(A&&) noexcept;
|
| 160 |
~A();
|
| 161 |
};
|
| 162 |
struct B {
|
| 163 |
+
B() noexcept;
|
| 164 |
B(const B&) = default; // implicit exception specification is noexcept(true)
|
| 165 |
+
B(B&&, int = (throw 42, 0)) noexcept;
|
| 166 |
~B() noexcept(false);
|
| 167 |
};
|
| 168 |
int n = 7;
|
| 169 |
struct D : public A, public B {
|
| 170 |
int * p = new int[n];
|
|
|
|
| 185 |
An exception specification is considered to be *needed* when:
|
| 186 |
|
| 187 |
- in an expression, the function is the unique lookup result or the
|
| 188 |
selected member of a set of overloaded functions ([[basic.lookup]],
|
| 189 |
[[over.match]], [[over.over]]);
|
| 190 |
+
- the function is odr-used [[basic.def.odr]] or, if it appears in an
|
| 191 |
unevaluated operand, would be odr-used if the expression were
|
| 192 |
potentially-evaluated;
|
| 193 |
- the exception specification is compared to that of another declaration
|
| 194 |
(e.g., an explicit specialization or an overriding virtual function);
|
| 195 |
- the function is defined; or
|
| 196 |
+
- the exception specification is needed for a defaulted function that
|
| 197 |
+
calls the function. \[*Note 3*: A defaulted declaration does not
|
| 198 |
+
require the exception specification of a base member function to be
|
| 199 |
+
evaluated until the implicit exception specification of the derived
|
| 200 |
+
function is needed, but an explicit *noexcept-specifier* needs the
|
| 201 |
+
implicit exception specification to compare against. — *end note*]
|
|
|
|
| 202 |
|
| 203 |
+
The exception specification of a defaulted function is evaluated as
|
| 204 |
+
described above only when needed; similarly, the *noexcept-specifier* of
|
| 205 |
+
a specialization of a function template or member function of a class
|
| 206 |
+
template is instantiated only when needed.
|
| 207 |
|