The changes are intended to be editorial only, not changing semantics. Due to the size of the changes, it seems prudent to have a full CWG review for these instead of leaving the issue to the project editor alone.
... If an allocation functionChange in 5.3.4 expr.new paragraph 15:declared withthat has a non-throwingexception-specificationexception specification (15.4 except.spec) fails to allocate storage, it shall return a null pointer. Any other allocation function that fails to allocate storage shall indicate failure only by throwing an exception (15.1 except.throw) of a type that would match a handler (15.3) of typestd::bad_alloc
(18.6.2.1).
[ Note: unless an allocation functionChange in 8.4.2 dcl.fct.def.default paragraph 2:is declared withhas a non-throwingexception-specificationexception specification (15.4 except.spec), it indicates failure to allocate storage by throwing astd::bad_alloc
exception (3.7.4.1 basic.stc.dynamic.allocation, Clause 15 except, 18.6.2.1); it returns a non-null pointer otherwise. If the allocation functionis declared withhas a non-throwingexception-specificationexception specification, it returns null to indicate failure to allocate storage and a non-null pointer otherwise. -- end note ] If the allocation function returns null, initialization shall not be done, the deallocation function shall not be called, and the value of the new-expression shall be null.
If a function that is explicitly defaultedChange in 12.1 class.ctor paragraph 5:has an explicit exception-specificationis declared with an exception specification that is not compatible (15.4 except.spec) with theexception-specificationexception specification on the implicit declaration, then ...
... [ Note: An implicitly-declared default constructor has anChange in 12.4 class.dtor paragraph 3:exception-specificationexception specification (15.4 except.spec). An explicitly-defaulted definition might have an implicitexception-specificationexception specification, see 8.4 dcl.fct.def. -- end note ]
A declaration of a destructor that does not have an exception-specificationChange in 12.5 class.free paragraph:is implicitly considered to have the same exception-specification as an implicit declarationhas the same exception specification as if had been implicitly declared (15.4 except.spec).
[ Note: If a deallocation function has no explicit exception-specification, itChange in 12.8 class.copy paragarph 14:is treated as if it were specified withhas a non-throwing exception specification (15.4 except.spec). -- end note ]noexcept(true)
... [ Note: An implicitly-declared copy/move constructor has anChange in 12.9 class.inhctor paragraph 3:exception-specificationimplied exception specification (15.4 except.spec). -- end note ]
[ Note: Default arguments are not inherited. Anexception-specificationexception specification is implied as specified in 15.4 except.spec. -- end note ]
Insert the section immediately before 5.17 [expr.ass], renumbering the sections that follow.
Move the following grammar production from 15 except paragraph 1:Move the following from 15 except paragraph 2:throw-expression:throw
assignment-expressionopt
A throw-expression is of type void
.
Move the following sentence from 15.1 except.throw paragraph 3:
Evaluating a throw-expression with an operand throws an exception; the type of the exception object is determined by removing any top-level cv-qualifiers from the static type of the operand and adjusting the type from "array of T" or "function returning T" to "pointer to T" or "pointer to function returning T," respectively.Move from 15.1 except.throw paragraphs 8 and 9, changing the highlighted parts::
A throw-expression with no operand rethrows the currently handled exception (15.3 except.handle). The exception is reactivated with the existing exception object; no new exception object is created. The exception is no longer considered to be caught; therefore, the value of
std::uncaught_exception()
(15.5.3 except.uncaught) will again be true. [ Example: code that must be executed because of an exception yet cannot completely handle the exception can be written like this:try { // ... } catch (...) { // catch all exceptions // respond (partially) to exception throw; // pass the exception to some // other handler }-- end example ]If no exception is presently being handled,
executingevaluating a throw-expression with no operand callsstd:: terminate()
(15.5.1 except.terminate).
Remove from 15 except paragraph 2:throw-expression: throw assignment-expressionopt
A try-block is a statement (Clause 6 stmt).Change in 15.1 except.throw paragraph 1:A throw-expression is of type void.[ Note: Within this Clause "try block" is taken to mean both try-block and function-try-block. -- end note ]
Throwing an exception transfers control to a handler. [ Note: An exception can be thrown from one of the following contexts: throw-expression (Remove from 15.1 expr.throw paragraph 3:see below5.17 expr.throw), allocation functions (3.7.4.1),dynamic_cast
(5.2.7),typeid
(5.2.8), new-expression (5.3.4), and standard library functions (17.5.1.4). -- end note ] ...
...Remove from 15.1 except throw paragraphs 8 and 9:Evaluating a throw-expression with an operand ..., respectively.
Change in 15.4 except.spec paragraph 1:
A throw-expression with no operand ...
If no exception is presently...
The exception specification of a function is a (possibly empty) set of types, indicating that the function might exit via an exception that matches a handler of one of the types in the set; the (conceptual) set of all types is used to denote that the function might exit via an exception of arbitrary type. If the set is empty, the function is said to have a non-throwing exception specification. The exception specification is either defined explicitlyReplace 15.4 except.spec paragraph 2:A function declaration lists exceptions that its function might directly or indirectly throwby using an exception-specification as a suffix ofitsa function declaration's declarator (8.3.5 dcl.fct) or implicitly. ...A noexcept-specificationnoexcept
is equivalent tonoexcept(true)
.
... A type denoted inChange in 15.4 except.spec paragraph 3:an exception-specificationa dynamic-exception-specification shall not denote an incomplete type or an rvalue reference type. A type denoted inan exception-specificationa dynamic-exception-specification shall not denote a pointer or reference to an incomplete type, other thancv void*"pointer to cvvoid
". A type cv T, "array of T", or "function returning T" denoted inan exception-specificationa dynamic-exception-specification is adjusted to type T, "pointer to T", or "pointer to function returning T", respectively. A dynamic-exception-specification denotes an exception specification that is the set of adjusted types specified thereby.
The exception-specificationChange in 15.4 except.spec paragraph 5:noexcept
ornoexcept(constant-expression)
, where the constant-expression yieldstrue
, denotes an exception specification that is the empty set. The exception-specificationnoexcept(constant-expression)
, where the constant-expression yieldsfalse
, or the absence of an exception-specification in a function declarator other than that for a destructor (12.4 class.dtor) or a deallocation function (3.7.4.2 basic.stc.dynamic.deallocation) denotes an exception specification that is the set of all types.Two exception-specifications are compatible if
:the sets of types they denote are the same.
both are non-throwing (see below), regardless of their form,both have the form noexcept(constant-expression) and the constant-expressions are equivalent, orboth are dynamic-exception-specifications that have the same set of adjusted types.
If a virtual function has anChange in 15.4 except.spec paragraph 8:exception-specificationexception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by theexception-specificationexception specification of the base class virtual function. [ Example: ... ]
A function is said to allow an exception of typeChange in 15.4 except.spec paragraph 9:E
ifthe constant-expression in its noexcept-specification evaluates to false or its dynamic-exception-specificationits exception specification contains a type T for which a handler of type T would be a match (15.3 except.handle) for an exception of typeE
. A function is said to allow all exceptions if its exception specification is the set of all types.
Whenever an exception is thrown and the search for a handler (15.3 except.handle) encounters the outermost block of a function with anChange in 15.4 except.spec paragraph 10:exception-specificationexception specification that does not allow the exception, then,... [ Note: A function can have multiple declarations with different non-throwing exception-specifications; for this purpose, the one on the function definition is used. -- end note ]
- if the function definition has
exception-specification isa dynamic-exception-specification, the functionstd::unexpected()
is called (15.5.2),- otherwise, the function
std::terminate()
is called (15.5.1).
The functionChange in 15.4 except.spec paragraph 12:std::unexpected()
may throw an exception thatwill satisfy the exception-specificationis allowed by the exception specification of the function for which it was invoked, and in this case the search for another handler will continue at the call ofthethat functionwith this exception-specification(see 15.5.2), or it may callstd::terminate()
.
Change in 15.4 except.spec paragraph 13:A function with no exception-specification or with an exception-specification of the formnoexcept(constant-expression )
where the constant-expression yields false allows all exceptions. An exception-specification is non-throwing if it is of the formthrow()
,noexcept
, ornoexcept(constant-expression )
where the constant-expression yields true. A function with a non-throwing exception-specification does not allow any exceptions.
[ Note: AnChange in 15.4 except.spec paragraph 15:exception-specificationexception specification is not considered part of a function's type; see 8.3.5 dcl.fct. -- end note ]
A deallocation function (3.7.4.2) with no explicit exception-specification has an exception specification that is the empty setChange in 15.5.1 except.terminate paragraph 1:is treated as if it were specified with.noexcept(true)
Change in 15.5.2 except.unexpected paragraph 1:
- ...
- when
std::unexpected
throwsexits via an exception which is not allowed by the previously violateddynamic-exception-specificationexception specification, andstd::bad_exception
is not included in thatdynamic-exception-specificationexception specification (15.5.2 except.unexpected), or- ...
If a function with a dynamic-exception-specificationChange in 15.5.2 except.unexpected paragraph 3:throwsexits via an exception that is notlisted in the dynamic-exception-specificationallowed by its exception specification, the functionstd::unexpected()
is called (D.11) immediately after completing the stack unwinding for the former function.
.... If itChange in 17.6.5.12 res.on.exception.handling paragraph 1:throws or rethrowsexits via an exception that the dynamic-exception-specification does not allow then the following happens: If the dynamic-exception-specification does not include the classstd::bad_exception
(18.8.2) then the functionstd::terminate()
is called, otherwise the thrown exception is replaced by an implementation-defined object ofthetypestd::bad_exception
and the search for another handler will continue at the call of the function whose dynamic-exception-specification was violated.[ Note: Thus, a dynamic-exception-specification guarantees that a function exits only via the listed exceptions
will be thrown. If the dynamic-exception-specification includes the typestd::bad_exception
then any exception not on the list may be replaced bystd::bad_exception
within the functionstd::unexpected()
. -- end note ]
Any of the functions defined in the C++ standard library can report a failure by throwing an exception of a type described in its Throws: paragraph. An implementation may strengthen theexception-specificationexception specification for a non-virtual function by adding a non-throwing noexcept-specification.