From Jason Turner

[except.spec]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmu7hy4cx/{from.md → to.md} +55 -51
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 ([[dcl.fct]]).
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]]); that constant expression is the exception specification
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 ([[dcl.init]]). The
24
- *noexcept-specifier* `noexcept` without a *constant-expression* is
25
- equivalent to the *noexcept-specifier* `noexcept(true)`. The
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 specfication is as specified
33
  below and no other declaration for that function shall have a
34
- *noexcept-specifier*. In an explicit instantiation ([[temp.explicit]])
35
- a *noexcept-specifier* may be specified, but is not required. If a
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(); // ill-formed
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]]) encounters the outermost block of a function with a
72
- non-throwing exception specification, the function `std::terminate()` is
73
- called ([[except.terminate]]).
74
 
75
- [*Note 1*: An implementation shall not reject an expression merely
76
- because, when executed, it throws or might throw an exception from a
77
- function with a non-throwing exception specification. — *end note*]
 
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 `e` is *potentially-throwing* if
96
 
97
- - `e` is a function call ([[expr.call]]) whose *postfix-expression* has
98
- a function type, or a pointer-to-function type, with a
99
  potentially-throwing exception specification, or
100
- - `e` implicitly invokes a function (such as an overloaded operator, an
101
  allocation function in a *new-expression*, a constructor for a
102
- function argument, or a destructor if `e` is a full-expression (
103
- [[intro.execution]])) that is potentially-throwing, or
104
- - `e` is a *throw-expression* ([[expr.throw]]), or
105
- - `e` is a `dynamic_cast` expression that casts to a reference type and
106
- requires a runtime check ([[expr.dynamic.cast]]), or
107
- - `e` is a `typeid` expression applied to a (possibly parenthesized)
108
  built-in unary `*` operator applied to a pointer to a polymorphic
109
- class type ([[expr.typeid]]), or
110
- - any of the immediate subexpressions ([[intro.execution]]) of `e` is
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 ([[except.ctor]]), their exception specifications do not
128
  contribute to the exception specification of the constructor, because an
129
- exception thrown from such a destructor would call `std::terminate`
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 subojects is 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
  [*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() throw();
159
  B(const B&) = default; // implicit exception specification is noexcept(true)
160
- B(B&&, int = (throw Y(), 0)) noexcept;
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 ([[basic.def.odr]]) or, if it appears in an
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 special member
192
- function that calls the function. \[*Note 3*: A defaulted declaration
193
- does not require the exception specification of a base member function
194
- to be evaluated until the implicit exception specification of the
195
- derived function is needed, but an explicit *noexcept-specifier* needs
196
- the implicit exception specification to compare
197
- against. — *end note*]
198
 
199
- The exception specification of a defaulted special member function is
200
- evaluated as described above only when needed; similarly, the
201
- *noexcept-specifier* of a specialization of a function template or
202
- member function of a class template is instantiated only when needed.
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