From Jason Turner

[except.spec]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpshb1tppb/{from.md → to.md} +33 -24
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
- '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,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
- 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.
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 1*:
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
- 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
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 even though, when called, `f` might throw
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 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
@@ -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 implicit
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 ([[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
@@ -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 3*:
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 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
 
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