|
4422 | 4422 | \indextext{declaration!default argument|)}%
|
4423 | 4423 | \indextext{declarator!meaning of|)}
|
4424 | 4424 |
|
| 4425 | +\rSec3[except.spec]{Exception specifications}% |
| 4426 | +\indextext{exception specification|(} |
| 4427 | + |
| 4428 | +\pnum |
| 4429 | +The predicate indicating whether a function cannot exit via an exception |
| 4430 | +is called the \defn{exception specification} of the function. |
| 4431 | +If the predicate is false, |
| 4432 | +the function has a |
| 4433 | +\indextext{exception specification!potentially-throwing}% |
| 4434 | +\defnx{potentially-throwing exception specification}% |
| 4435 | +{potentially-throwing!exception specification}, |
| 4436 | +otherwise it has a |
| 4437 | +\indextext{exception specification!non-throwing}% |
| 4438 | +\defn{non-throwing exception specification}. |
| 4439 | +The exception specification is either defined implicitly, |
| 4440 | +or defined explicitly |
| 4441 | +by using a \grammarterm{noexcept-specifier} |
| 4442 | +as a suffix of a function declarator\iref{dcl.fct}. |
| 4443 | + |
| 4444 | +\begin{bnf} |
| 4445 | +\nontermdef{noexcept-specifier}\br |
| 4446 | + \keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br |
| 4447 | + \keyword{noexcept}\br |
| 4448 | +\end{bnf} |
| 4449 | + |
| 4450 | +\pnum |
| 4451 | +\indextext{exception specification!noexcept!constant expression and}% |
| 4452 | +In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression}, |
| 4453 | +if supplied, shall be a contextually converted constant expression |
| 4454 | +of type \keyword{bool}\iref{expr.const}; |
| 4455 | +that constant expression is the exception specification of |
| 4456 | +the function type in which the \grammarterm{noexcept-specifier} appears. |
| 4457 | +A \tcode{(} token that follows \keyword{noexcept} is part of the |
| 4458 | +\grammarterm{noexcept-specifier} and does not commence an |
| 4459 | +initializer\iref{dcl.init}. |
| 4460 | +The \grammarterm{noexcept-specifier} \keyword{noexcept} |
| 4461 | +without a \grammarterm{constant-expression} |
| 4462 | +is |
| 4463 | +equivalent to the \grammarterm{noexcept-specifier} |
| 4464 | +\tcode{\keyword{noexcept}(\keyword{true})}. |
| 4465 | +\begin{example} |
| 4466 | +\begin{codeblock} |
| 4467 | +void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool} |
| 4468 | +void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing |
| 4469 | +\end{codeblock} |
| 4470 | +\end{example} |
| 4471 | + |
| 4472 | +\pnum |
| 4473 | +If a declaration of a function |
| 4474 | +does not have a \grammarterm{noexcept-specifier}, |
| 4475 | +the declaration has a potentially throwing exception specification |
| 4476 | +unless it is a destructor or a deallocation function |
| 4477 | +or is defaulted on its first declaration, |
| 4478 | +in which cases the exception specification |
| 4479 | +is as specified below |
| 4480 | +and no other declaration for that function |
| 4481 | +shall have a \grammarterm{noexcept-specifier}. |
| 4482 | +In an explicit instantiation\iref{temp.explicit} |
| 4483 | +a \grammarterm{noexcept-specifier} may be specified, |
| 4484 | +but is not required. |
| 4485 | +If a \grammarterm{noexcept-specifier} is specified |
| 4486 | +in an explicit instantiation, |
| 4487 | +the exception specification shall be the same as |
| 4488 | +the exception specification of all other declarations of that function. |
| 4489 | +A diagnostic is required only if the |
| 4490 | +exception specifications are not the same |
| 4491 | +within a single translation unit. |
| 4492 | + |
| 4493 | +\pnum |
| 4494 | +\indextext{exception specification!virtual function and}% |
| 4495 | +If a virtual function has a |
| 4496 | +non-throwing exception specification, |
| 4497 | +all declarations, including the definition, of any function |
| 4498 | +that overrides that virtual function in any derived class |
| 4499 | +shall have a non-throwing |
| 4500 | +exception specification, |
| 4501 | +unless the overriding function is defined as deleted. |
| 4502 | +\begin{example} |
| 4503 | +\begin{codeblock} |
| 4504 | +struct B { |
| 4505 | + virtual void f() noexcept; |
| 4506 | + virtual void g(); |
| 4507 | + virtual void h() noexcept = delete; |
| 4508 | +}; |
| 4509 | + |
| 4510 | +struct D: B { |
| 4511 | + void f(); // error |
| 4512 | + void g() noexcept; // OK |
| 4513 | + void h() = delete; // OK |
| 4514 | +}; |
| 4515 | +\end{codeblock} |
| 4516 | + |
| 4517 | +The declaration of |
| 4518 | +\tcode{D::f} |
| 4519 | +is ill-formed because it |
| 4520 | +has a potentially-throwing exception specification, |
| 4521 | +whereas |
| 4522 | +\tcode{B::f} |
| 4523 | +has a non-throwing exception specification. |
| 4524 | +\end{example} |
| 4525 | + |
| 4526 | +\pnum |
| 4527 | +An expression $E$ is |
| 4528 | +\defnx{potentially-throwing}{potentially-throwing!expression} if |
| 4529 | +\begin{itemize} |
| 4530 | +\item |
| 4531 | +$E$ is a \grammarterm{throw-expression}\iref{expr.throw}, |
| 4532 | +or |
| 4533 | +\item |
| 4534 | +$E$ implicitly invokes a function |
| 4535 | +(such as an overloaded operator, |
| 4536 | +an allocation function in a \grammarterm{new-expression}, |
| 4537 | +a constructor for a function argument, |
| 4538 | +or a destructor if $E$ is a full-expression\iref{intro.execution}) |
| 4539 | +that has a potentially-throwing exception specification, |
| 4540 | +or |
| 4541 | +\item |
| 4542 | +any of the immediate subexpressions\iref{intro.execution} |
| 4543 | +of $E$ is potentially-throwing, |
| 4544 | +or |
| 4545 | +\item |
| 4546 | +$E$ is a function call\iref{expr.call} |
| 4547 | +whose \grammarterm{postfix-expression} |
| 4548 | +has a function type, |
| 4549 | +or a pointer-to-function type, |
| 4550 | +with a potentially-throwing exception specification, |
| 4551 | +or |
| 4552 | +\item |
| 4553 | +$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and |
| 4554 | +requires a runtime check\iref{expr.dynamic.cast}, |
| 4555 | +or |
| 4556 | +\item |
| 4557 | +$E$ is a \keyword{typeid} expression applied to a |
| 4558 | +(possibly parenthesized) built-in unary \tcode{*} operator |
| 4559 | +applied to a pointer to a |
| 4560 | +polymorphic class type\iref{expr.typeid}. |
| 4561 | +\end{itemize} |
| 4562 | + |
| 4563 | +\pnum |
| 4564 | +An implicitly-declared constructor for a class \tcode{X}, |
| 4565 | +or a constructor without a \grammarterm{noexcept-specifier} |
| 4566 | +that is defaulted on its first declaration, |
| 4567 | +has a potentially-throwing exception specification |
| 4568 | +if and only if |
| 4569 | +any of the following constructs is potentially-throwing: |
| 4570 | +\begin{itemize} |
| 4571 | +\item |
| 4572 | +the invocation of a constructor selected by overload resolution |
| 4573 | +in the implicit definition of the constructor |
| 4574 | +for class \tcode{X} |
| 4575 | +to initialize a potentially constructed subobject, or |
| 4576 | +\item |
| 4577 | +a subexpression of such an initialization, |
| 4578 | +such as a default argument expression, or, |
| 4579 | +\item |
| 4580 | +for a default constructor, a default member initializer. |
| 4581 | +\end{itemize} |
| 4582 | +\begin{note} |
| 4583 | +Even though destructors for fully-constructed subobjects |
| 4584 | +are invoked when an exception is thrown |
| 4585 | +during the execution of a constructor\iref{except.ctor}, |
| 4586 | +their exception specifications do not contribute |
| 4587 | +to the exception specification of the constructor, |
| 4588 | +because an exception thrown from such a destructor |
| 4589 | +would call the function \tcode{std::terminate} |
| 4590 | +rather than escape the constructor\iref{except.throw,except.terminate}. |
| 4591 | +\end{note} |
| 4592 | + |
| 4593 | +\pnum |
| 4594 | +The exception specification for an implicitly-declared destructor, |
| 4595 | +or a destructor without a \grammarterm{noexcept-specifier}, |
| 4596 | +is potentially-throwing if and only if |
| 4597 | +any of the destructors |
| 4598 | +for any of its potentially constructed subobjects |
| 4599 | +has a potentially-throwing exception specification or |
| 4600 | +the destructor is virtual and the destructor of any virtual base class |
| 4601 | +has a potentially-throwing exception specification. |
| 4602 | + |
| 4603 | +\pnum |
| 4604 | +The exception specification for an implicitly-declared assignment operator, |
| 4605 | +or an assignment-operator without a \grammarterm{noexcept-specifier} |
| 4606 | +that is defaulted on its first declaration, |
| 4607 | +is potentially-throwing if and only if |
| 4608 | +the invocation of any assignment operator |
| 4609 | +in the implicit definition is potentially-throwing. |
| 4610 | + |
| 4611 | +\pnum |
| 4612 | +A deallocation function\iref{basic.stc.dynamic.deallocation} |
| 4613 | +with no explicit \grammarterm{noexcept-specifier} |
| 4614 | +has a non-throwing exception specification. |
| 4615 | + |
| 4616 | +\pnum |
| 4617 | +The exception specification for a comparison operator function\iref{over.binary} |
| 4618 | +without a \grammarterm{noexcept-specifier} |
| 4619 | +that is defaulted on its first declaration |
| 4620 | +is potentially-throwing if and only if |
| 4621 | +any expression |
| 4622 | +in the implicit definition is potentially-throwing. |
| 4623 | + |
| 4624 | +\pnum |
| 4625 | +\begin{example} |
| 4626 | +\begin{codeblock} |
| 4627 | +struct A { |
| 4628 | + A(int = (A(5), 0)) noexcept; |
| 4629 | + A(const A&) noexcept; |
| 4630 | + A(A&&) noexcept; |
| 4631 | + ~A(); |
| 4632 | +}; |
| 4633 | +struct B { |
| 4634 | + B() noexcept; |
| 4635 | + B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})} |
| 4636 | + B(B&&, int = (throw 42, 0)) noexcept; |
| 4637 | + ~B() noexcept(false); |
| 4638 | +}; |
| 4639 | +int n = 7; |
| 4640 | +struct D : public A, public B { |
| 4641 | + int * p = new int[n]; |
| 4642 | + // \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length} |
| 4643 | + // \tcode{D::D(const D\&)} non-throwing |
| 4644 | + // \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw |
| 4645 | + // \tcode{D::\~D()} potentially-throwing |
| 4646 | +}; |
| 4647 | +\end{codeblock} |
| 4648 | +Furthermore, if |
| 4649 | +\tcode{A::\~{}A()} |
| 4650 | +were virtual, |
| 4651 | +the program would be ill-formed since a function that overrides a virtual |
| 4652 | +function from a base class |
| 4653 | +shall not have a potentially-throwing exception specification |
| 4654 | +if the base class function has a non-throwing exception specification. |
| 4655 | +\end{example} |
| 4656 | + |
| 4657 | +\pnum |
| 4658 | +An exception specification is considered to be \defnx{needed}{needed!exception specification} when: |
| 4659 | +\begin{itemize} |
| 4660 | +\item in an expression, the function is selected by |
| 4661 | +overload resolution\iref{over.match,over.over}; |
| 4662 | + |
| 4663 | +\item the function is odr-used\iref{term.odr.use} or, if it appears in an |
| 4664 | +unevaluated operand, would be odr-used if the expression were |
| 4665 | +potentially-evaluated; |
| 4666 | + |
| 4667 | +\item the exception specification is compared to that of another |
| 4668 | +declaration (e.g., an explicit specialization or an overriding virtual |
| 4669 | +function); |
| 4670 | + |
| 4671 | +\item the function is defined; or |
| 4672 | + |
| 4673 | +\item the exception specification is needed for a defaulted |
| 4674 | +function that calls the function. |
| 4675 | +\begin{note} |
| 4676 | +A defaulted declaration does not require the |
| 4677 | +exception specification of a base member function to be evaluated |
| 4678 | +until the implicit exception specification of the derived |
| 4679 | +function is needed, but an explicit \grammarterm{noexcept-specifier} needs |
| 4680 | +the implicit exception specification to compare against. |
| 4681 | +\end{note} |
| 4682 | +\end{itemize} |
| 4683 | +The exception specification of a defaulted |
| 4684 | +function is evaluated as described above only when needed; similarly, the |
| 4685 | +\grammarterm{noexcept-specifier} of a specialization of a function |
| 4686 | +template or member function of a class template is instantiated only when |
| 4687 | +needed. |
| 4688 | +% |
| 4689 | +\indextext{exception specification|)} |
| 4690 | +\indextext{exception handling|)} |
| 4691 | + |
4425 | 4692 | \rSec1[dcl.init]{Initializers}%
|
4426 | 4693 |
|
4427 | 4694 | \rSec2[dcl.init.general]{General}%
|
|
0 commit comments