tmp/tmpshb1tppb/{from.md → to.md}
RENAMED
|
@@ -8,12 +8,12 @@ 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 |
-
|
| 14 |
-
|
| 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
|
|
@@ -21,30 +21,39 @@ 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 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
|
| 39 |
If a virtual function has a non-throwing exception specification, all
|
| 40 |
declarations, including the definition, of any function that overrides
|
| 41 |
that virtual function in any derived class shall have a non-throwing
|
| 42 |
exception specification, unless the overriding function is defined as
|
| 43 |
deleted.
|
| 44 |
|
| 45 |
-
[*Example
|
| 46 |
|
| 47 |
``` cpp
|
| 48 |
struct B {
|
| 49 |
virtual void f() noexcept;
|
| 50 |
virtual void g();
|
|
@@ -65,29 +74,29 @@ non-throwing exception specification.
|
|
| 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 |
-
|
| 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
|
| 78 |
|
| 79 |
``` cpp
|
| 80 |
extern void f(); // potentially-throwing
|
| 81 |
|
| 82 |
void g() noexcept {
|
| 83 |
f(); // valid, even if f throws
|
| 84 |
throw 42; // valid, effectively a call to std::terminate
|
| 85 |
}
|
| 86 |
```
|
| 87 |
|
| 88 |
-
The call to `f` is well-formed
|
| 89 |
an exception.
|
| 90 |
|
| 91 |
— *end example*]
|
| 92 |
|
| 93 |
An expression E is *potentially-throwing* if
|
|
@@ -96,11 +105,12 @@ An expression E is *potentially-throwing* if
|
|
| 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
|
|
|
|
| 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
|
|
@@ -111,31 +121,31 @@ An expression E is *potentially-throwing* if
|
|
| 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
|
| 114 |
only if any of the following constructs is potentially-throwing:
|
| 115 |
|
| 116 |
-
- a constructor selected by overload resolution in the
|
| 117 |
-
definition of the constructor for class `X` to initialize a
|
| 118 |
potentially constructed subobject, or
|
| 119 |
- a subexpression of such an initialization, such as a default argument
|
| 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
|
| 129 |
-
[[except.terminate]]
|
| 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
|
| 135 |
-
|
| 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
|
|
@@ -148,11 +158,11 @@ specification.
|
|
| 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
|
| 154 |
|
| 155 |
``` cpp
|
| 156 |
struct A {
|
| 157 |
A(int = (A(5), 0)) noexcept;
|
| 158 |
A(const A&) noexcept;
|
|
@@ -182,14 +192,13 @@ base class function has a non-throwing exception specification.
|
|
| 182 |
|
| 183 |
— *end example*]
|
| 184 |
|
| 185 |
An exception specification is considered to be *needed* when:
|
| 186 |
|
| 187 |
-
- in an expression, the function is
|
| 188 |
-
|
| 189 |
-
|
| 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
|
|
|
|
| 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
|
|
|
|
| 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 |
+
[*Example 1*:
|
| 27 |
+
|
| 28 |
+
``` cpp
|
| 29 |
+
void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type bool
|
| 30 |
+
void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type bool is non-narrowing
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
— *end example*]
|
| 34 |
+
|
| 35 |
If a declaration of a function does not have a *noexcept-specifier*, the
|
| 36 |
declaration has a potentially throwing exception specification unless it
|
| 37 |
is a destructor or a deallocation function or is defaulted on its first
|
| 38 |
declaration, in which cases the exception specification is as specified
|
| 39 |
below and no other declaration for that function shall have a
|
| 40 |
*noexcept-specifier*. In an explicit instantiation [[temp.explicit]] a
|
| 41 |
*noexcept-specifier* may be specified, but is not required. If a
|
| 42 |
+
*noexcept-specifier* is specified in an explicit instantiation, the
|
| 43 |
+
exception specification shall be the same as the exception specification
|
| 44 |
+
of all other declarations of that function. A diagnostic is required
|
| 45 |
+
only if the exception specifications are not the same within a single
|
| 46 |
+
translation unit.
|
| 47 |
|
| 48 |
If a virtual function has a non-throwing exception specification, all
|
| 49 |
declarations, including the definition, of any function that overrides
|
| 50 |
that virtual function in any derived class shall have a non-throwing
|
| 51 |
exception specification, unless the overriding function is defined as
|
| 52 |
deleted.
|
| 53 |
|
| 54 |
+
[*Example 2*:
|
| 55 |
|
| 56 |
``` cpp
|
| 57 |
struct B {
|
| 58 |
virtual void f() noexcept;
|
| 59 |
virtual void g();
|
|
|
|
| 74 |
— *end example*]
|
| 75 |
|
| 76 |
Whenever an exception is thrown and the search for a handler
|
| 77 |
[[except.handle]] encounters the outermost block of a function with a
|
| 78 |
non-throwing exception specification, the function `std::terminate` is
|
| 79 |
+
invoked [[except.terminate]].
|
| 80 |
|
| 81 |
[*Note 1*: An implementation is not permitted to reject an expression
|
| 82 |
merely because, when executed, it throws or might throw an exception
|
| 83 |
from a function with a non-throwing exception
|
| 84 |
specification. — *end note*]
|
| 85 |
|
| 86 |
+
[*Example 3*:
|
| 87 |
|
| 88 |
``` cpp
|
| 89 |
extern void f(); // potentially-throwing
|
| 90 |
|
| 91 |
void g() noexcept {
|
| 92 |
f(); // valid, even if f throws
|
| 93 |
throw 42; // valid, effectively a call to std::terminate
|
| 94 |
}
|
| 95 |
```
|
| 96 |
|
| 97 |
+
The call to `f` is well-formed despite the possibility for it to throw
|
| 98 |
an exception.
|
| 99 |
|
| 100 |
— *end example*]
|
| 101 |
|
| 102 |
An expression E is *potentially-throwing* if
|
|
|
|
| 105 |
function type, or a pointer-to-function type, with a
|
| 106 |
potentially-throwing exception specification, or
|
| 107 |
- E implicitly invokes a function (such as an overloaded operator, an
|
| 108 |
allocation function in a *new-expression*, a constructor for a
|
| 109 |
function argument, or a destructor if E is a full-expression
|
| 110 |
+
[[intro.execution]]) that has a potentially-throwing exception
|
| 111 |
+
specification, or
|
| 112 |
- E is a *throw-expression* [[expr.throw]], or
|
| 113 |
- E is a `dynamic_cast` expression that casts to a reference type and
|
| 114 |
requires a runtime check [[expr.dynamic.cast]], or
|
| 115 |
- E is a `typeid` expression applied to a (possibly parenthesized)
|
| 116 |
built-in unary `*` operator applied to a pointer to a polymorphic
|
|
|
|
| 121 |
An implicitly-declared constructor for a class `X`, or a constructor
|
| 122 |
without a *noexcept-specifier* that is defaulted on its first
|
| 123 |
declaration, has a potentially-throwing exception specification if and
|
| 124 |
only if any of the following constructs is potentially-throwing:
|
| 125 |
|
| 126 |
+
- the invocation of a constructor selected by overload resolution in the
|
| 127 |
+
implicit definition of the constructor for class `X` to initialize a
|
| 128 |
potentially constructed subobject, or
|
| 129 |
- a subexpression of such an initialization, such as a default argument
|
| 130 |
expression, or,
|
| 131 |
- for a default constructor, a default member initializer.
|
| 132 |
|
| 133 |
[*Note 2*: Even though destructors for fully-constructed subobjects are
|
| 134 |
invoked when an exception is thrown during the execution of a
|
| 135 |
constructor [[except.ctor]], their exception specifications do not
|
| 136 |
contribute to the exception specification of the constructor, because an
|
| 137 |
exception thrown from such a destructor would call the function
|
| 138 |
+
`std::terminate` rather than escape the constructor
|
| 139 |
+
[[except.throw]], [[except.terminate]]. — *end note*]
|
| 140 |
|
| 141 |
The exception specification for an implicitly-declared destructor, or a
|
| 142 |
destructor without a *noexcept-specifier*, is potentially-throwing if
|
| 143 |
and only if any of the destructors for any of its potentially
|
| 144 |
+
constructed subobjects has a potentially-throwing exception
|
| 145 |
+
specification or the destructor is virtual and the destructor of any
|
| 146 |
+
virtual base class has a potentially-throwing exception specification.
|
| 147 |
|
| 148 |
The exception specification for an implicitly-declared assignment
|
| 149 |
operator, or an assignment-operator without a *noexcept-specifier* that
|
| 150 |
is defaulted on its first declaration, is potentially-throwing if and
|
| 151 |
only if the invocation of any assignment operator in the implicit
|
|
|
|
| 158 |
The exception specification for a comparison operator function
|
| 159 |
[[over.binary]] without a *noexcept-specifier* that is defaulted on its
|
| 160 |
first declaration is potentially-throwing if and only if any expression
|
| 161 |
in the implicit definition is potentially-throwing.
|
| 162 |
|
| 163 |
+
[*Example 4*:
|
| 164 |
|
| 165 |
``` cpp
|
| 166 |
struct A {
|
| 167 |
A(int = (A(5), 0)) noexcept;
|
| 168 |
A(const A&) noexcept;
|
|
|
|
| 192 |
|
| 193 |
— *end example*]
|
| 194 |
|
| 195 |
An exception specification is considered to be *needed* when:
|
| 196 |
|
| 197 |
+
- in an expression, the function is selected by overload resolution
|
| 198 |
+
[[over.match]], [[over.over]];
|
| 199 |
+
- the function is odr-used [[term.odr.use]] or, if it appears in an
|
|
|
|
| 200 |
unevaluated operand, would be odr-used if the expression were
|
| 201 |
potentially-evaluated;
|
| 202 |
- the exception specification is compared to that of another declaration
|
| 203 |
(e.g., an explicit specialization or an overriding virtual function);
|
| 204 |
- the function is defined; or
|