|
4109 | 4109 | \end{footnote}
|
4110 | 4110 | \indextext{declarator!function|)}
|
4111 | 4111 |
|
| 4112 | +\rSec2[except.spec]{Exception specifications}% |
| 4113 | +\indextext{exception specification|(} |
| 4114 | + |
| 4115 | +\pnum |
| 4116 | +The predicate indicating whether a function cannot exit via an exception |
| 4117 | +is called the \defn{exception specification} of the function. |
| 4118 | +If the predicate is false, |
| 4119 | +the function has a |
| 4120 | +\indextext{exception specification!potentially-throwing}% |
| 4121 | +\defnx{potentially-throwing exception specification}% |
| 4122 | +{potentially-throwing!exception specification}, |
| 4123 | +otherwise it has a |
| 4124 | +\indextext{exception specification!non-throwing}% |
| 4125 | +\defn{non-throwing exception specification}. |
| 4126 | +The exception specification is either defined implicitly, |
| 4127 | +or defined explicitly |
| 4128 | +by using a \grammarterm{noexcept-specifier} |
| 4129 | +as a suffix of a function declarator\iref{dcl.fct}. |
| 4130 | + |
| 4131 | +\begin{bnf} |
| 4132 | +\nontermdef{noexcept-specifier}\br |
| 4133 | + \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br |
| 4134 | + \keyword{noexcept}\br |
| 4135 | +\end{bnf} |
| 4136 | + |
| 4137 | +\pnum |
| 4138 | +\indextext{exception specification!noexcept!constant expression and}% |
| 4139 | +In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression}, |
| 4140 | +if supplied, shall be a contextually converted constant expression |
| 4141 | +of type \keyword{bool}\iref{expr.const}; |
| 4142 | +that constant expression is the exception specification of |
| 4143 | +the function type in which the \grammarterm{noexcept-specifier} appears. |
| 4144 | +A \tcode{(} token that follows \keyword{noexcept} is part of the |
| 4145 | +\grammarterm{noexcept-specifier} and does not commence an |
| 4146 | +initializer\iref{dcl.init}. |
| 4147 | +The \grammarterm{noexcept-specifier} \keyword{noexcept} |
| 4148 | +without a \grammarterm{constant-expression} |
| 4149 | +is |
| 4150 | +equivalent to the \grammarterm{noexcept-specifier} |
| 4151 | +\tcode{\keyword{noexcept}(\keyword{true})}. |
| 4152 | +\begin{example} |
| 4153 | +\begin{codeblock} |
| 4154 | +void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool} |
| 4155 | +void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing |
| 4156 | +\end{codeblock} |
| 4157 | +\end{example} |
| 4158 | + |
| 4159 | +\pnum |
| 4160 | +If a declaration of a function |
| 4161 | +does not have a \grammarterm{noexcept-specifier}, |
| 4162 | +the declaration has a potentially throwing exception specification |
| 4163 | +unless it is a destructor or a deallocation function |
| 4164 | +or is defaulted on its first declaration, |
| 4165 | +in which cases the exception specification |
| 4166 | +is as specified below |
| 4167 | +and no other declaration for that function |
| 4168 | +shall have a \grammarterm{noexcept-specifier}. |
| 4169 | +In an explicit instantiation\iref{temp.explicit} |
| 4170 | +a \grammarterm{noexcept-specifier} may be specified, |
| 4171 | +but is not required. |
| 4172 | +If a \grammarterm{noexcept-specifier} is specified |
| 4173 | +in an explicit instantiation, |
| 4174 | +the exception specification shall be the same as |
| 4175 | +the exception specification of all other declarations of that function. |
| 4176 | +A diagnostic is required only if the |
| 4177 | +exception specifications are not the same |
| 4178 | +within a single translation unit. |
| 4179 | + |
| 4180 | +\pnum |
| 4181 | +\indextext{exception specification!virtual function and}% |
| 4182 | +If a virtual function has a |
| 4183 | +non-throwing exception specification, |
| 4184 | +all declarations, including the definition, of any function |
| 4185 | +that overrides that virtual function in any derived class |
| 4186 | +shall have a non-throwing |
| 4187 | +exception specification, |
| 4188 | +unless the overriding function is defined as deleted. |
| 4189 | +\begin{example} |
| 4190 | +\begin{codeblock} |
| 4191 | +struct B { |
| 4192 | + virtual void f() noexcept; |
| 4193 | + virtual void g(); |
| 4194 | + virtual void h() noexcept = delete; |
| 4195 | +}; |
| 4196 | + |
| 4197 | +struct D: B { |
| 4198 | + void f(); // error |
| 4199 | + void g() noexcept; // OK |
| 4200 | + void h() = delete; // OK |
| 4201 | +}; |
| 4202 | +\end{codeblock} |
| 4203 | + |
| 4204 | +The declaration of |
| 4205 | +\tcode{D::f} |
| 4206 | +is ill-formed because it |
| 4207 | +has a potentially-throwing exception specification, |
| 4208 | +whereas |
| 4209 | +\tcode{B::f} |
| 4210 | +has a non-throwing exception specification. |
| 4211 | +\end{example} |
| 4212 | + |
| 4213 | +\pnum |
| 4214 | +An expression $E$ is |
| 4215 | +\defnx{potentially-throwing}{potentially-throwing!expression} if |
| 4216 | +\begin{itemize} |
| 4217 | +\item |
| 4218 | +$E$ is a function call\iref{expr.call} |
| 4219 | +whose \grammarterm{postfix-expression} |
| 4220 | +has a function type, |
| 4221 | +or a pointer-to-function type, |
| 4222 | +with a potentially-throwing exception specification, |
| 4223 | +or |
| 4224 | +\item |
| 4225 | +$E$ implicitly invokes a function |
| 4226 | +(such as an overloaded operator, |
| 4227 | +an allocation function in a \grammarterm{new-expression}, |
| 4228 | +a constructor for a function argument, |
| 4229 | +or a destructor if $E$ is a full-expression\iref{intro.execution}) |
| 4230 | +that has a potentially-throwing exception specification, |
| 4231 | +or |
| 4232 | +\item |
| 4233 | +$E$ is a \grammarterm{throw-expression}\iref{expr.throw}, |
| 4234 | +or |
| 4235 | +\item |
| 4236 | +$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and |
| 4237 | +requires a runtime check\iref{expr.dynamic.cast}, |
| 4238 | +or |
| 4239 | +\item |
| 4240 | +$E$ is a \keyword{typeid} expression applied to a |
| 4241 | +(possibly parenthesized) built-in unary \tcode{*} operator |
| 4242 | +applied to a pointer to a |
| 4243 | +polymorphic class type\iref{expr.typeid}, |
| 4244 | +or |
| 4245 | +\item |
| 4246 | +any of the immediate subexpressions\iref{intro.execution} |
| 4247 | +of $E$ is potentially-throwing. |
| 4248 | +\end{itemize} |
| 4249 | + |
| 4250 | +\pnum |
| 4251 | +An implicitly-declared constructor for a class \tcode{X}, |
| 4252 | +or a constructor without a \grammarterm{noexcept-specifier} |
| 4253 | +that is defaulted on its first declaration, |
| 4254 | +has a potentially-throwing exception specification |
| 4255 | +if and only if |
| 4256 | +any of the following constructs is potentially-throwing: |
| 4257 | +\begin{itemize} |
| 4258 | +\item |
| 4259 | +the invocation of a constructor selected by overload resolution |
| 4260 | +in the implicit definition of the constructor |
| 4261 | +for class \tcode{X} |
| 4262 | +to initialize a potentially constructed subobject, or |
| 4263 | +\item |
| 4264 | +a subexpression of such an initialization, |
| 4265 | +such as a default argument expression, or, |
| 4266 | +\item |
| 4267 | +for a default constructor, a default member initializer. |
| 4268 | +\end{itemize} |
| 4269 | +\begin{note} |
| 4270 | +Even though destructors for fully-constructed subobjects |
| 4271 | +are invoked when an exception is thrown |
| 4272 | +during the execution of a constructor\iref{except.ctor}, |
| 4273 | +their exception specifications do not contribute |
| 4274 | +to the exception specification of the constructor, |
| 4275 | +because an exception thrown from such a destructor |
| 4276 | +would call the function \tcode{std::terminate} |
| 4277 | +rather than escape the constructor\iref{except.throw,except.terminate}. |
| 4278 | +\end{note} |
| 4279 | + |
| 4280 | +\pnum |
| 4281 | +The exception specification for an implicitly-declared destructor, |
| 4282 | +or a destructor without a \grammarterm{noexcept-specifier}, |
| 4283 | +is potentially-throwing if and only if |
| 4284 | +any of the destructors |
| 4285 | +for any of its potentially constructed subobjects |
| 4286 | +has a potentially-throwing exception specification or |
| 4287 | +the destructor is virtual and the destructor of any virtual base class |
| 4288 | +has a potentially-throwing exception specification. |
| 4289 | + |
| 4290 | +\pnum |
| 4291 | +The exception specification for an implicitly-declared assignment operator, |
| 4292 | +or an assignment-operator without a \grammarterm{noexcept-specifier} |
| 4293 | +that is defaulted on its first declaration, |
| 4294 | +is potentially-throwing if and only if |
| 4295 | +the invocation of any assignment operator |
| 4296 | +in the implicit definition is potentially-throwing. |
| 4297 | + |
| 4298 | +\pnum |
| 4299 | +A deallocation function\iref{basic.stc.dynamic.deallocation} |
| 4300 | +with no explicit \grammarterm{noexcept-specifier} |
| 4301 | +has a non-throwing exception specification. |
| 4302 | + |
| 4303 | +\pnum |
| 4304 | +The exception specification for a comparison operator function\iref{over.binary} |
| 4305 | +without a \grammarterm{noexcept-specifier} |
| 4306 | +that is defaulted on its first declaration |
| 4307 | +is potentially-throwing if and only if |
| 4308 | +any expression |
| 4309 | +in the implicit definition is potentially-throwing. |
| 4310 | + |
| 4311 | +\pnum |
| 4312 | +\begin{example} |
| 4313 | +\begin{codeblock} |
| 4314 | +struct A { |
| 4315 | + A(int = (A(5), 0)) noexcept; |
| 4316 | + A(const A&) noexcept; |
| 4317 | + A(A&&) noexcept; |
| 4318 | + ~A(); |
| 4319 | +}; |
| 4320 | +struct B { |
| 4321 | + B() noexcept; |
| 4322 | + B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})} |
| 4323 | + B(B&&, int = (throw 42, 0)) noexcept; |
| 4324 | + ~B() noexcept(false); |
| 4325 | +}; |
| 4326 | +int n = 7; |
| 4327 | +struct D : public A, public B { |
| 4328 | + int * p = new int[n]; |
| 4329 | + // \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length} |
| 4330 | + // \tcode{D::D(const D\&)} non-throwing |
| 4331 | + // \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw |
| 4332 | + // \tcode{D::\~D()} potentially-throwing |
| 4333 | +}; |
| 4334 | +\end{codeblock} |
| 4335 | +Furthermore, if |
| 4336 | +\tcode{A::\~{}A()} |
| 4337 | +were virtual, |
| 4338 | +the program would be ill-formed since a function that overrides a virtual |
| 4339 | +function from a base class |
| 4340 | +shall not have a potentially-throwing exception specification |
| 4341 | +if the base class function has a non-throwing exception specification. |
| 4342 | +\end{example} |
| 4343 | + |
| 4344 | +\pnum |
| 4345 | +An exception specification is considered to be \defnx{needed}{needed!exception specification} when: |
| 4346 | +\begin{itemize} |
| 4347 | +\item in an expression, the function is selected by |
| 4348 | +overload resolution\iref{over.match,over.over}; |
| 4349 | + |
| 4350 | +\item the function is odr-used\iref{term.odr.use} or, if it appears in an |
| 4351 | +unevaluated operand, would be odr-used if the expression were |
| 4352 | +potentially-evaluated; |
| 4353 | + |
| 4354 | +\item the exception specification is compared to that of another |
| 4355 | +declaration (e.g., an explicit specialization or an overriding virtual |
| 4356 | +function); |
| 4357 | + |
| 4358 | +\item the function is defined; or |
| 4359 | + |
| 4360 | +\item the exception specification is needed for a defaulted |
| 4361 | +function that calls the function. |
| 4362 | +\begin{note} |
| 4363 | +A defaulted declaration does not require the |
| 4364 | +exception specification of a base member function to be evaluated |
| 4365 | +until the implicit exception specification of the derived |
| 4366 | +function is needed, but an explicit \grammarterm{noexcept-specifier} needs |
| 4367 | +the implicit exception specification to compare against. |
| 4368 | +\end{note} |
| 4369 | +\end{itemize} |
| 4370 | +The exception specification of a defaulted |
| 4371 | +function is evaluated as described above only when needed; similarly, the |
| 4372 | +\grammarterm{noexcept-specifier} of a specialization of a function |
| 4373 | +template or member function of a class template is instantiated only when |
| 4374 | +needed. |
| 4375 | +% |
| 4376 | +\indextext{exception specification|)} |
| 4377 | + |
4112 | 4378 | \rSec3[dcl.fct.default]{Default arguments}%
|
4113 | 4379 | \indextext{declaration!default argument|(}
|
4114 | 4380 |
|
|
0 commit comments