CWG Issue 1431 (original) (raw)
This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 118e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-11-05
1431. Exceptions from other than _throw-expression_s
Section: Clause 14 [except]Status: CD3Submitter: Nikolay IvchenkovDate: 2011-12-16
[Moved to DR at the October, 2012 meeting.]
There are a number of places in the Standard that appear to assume that exceptions are only thrown by _throw-expression_s. Various other constructs, such as dynamic_casts,typeid, _new-expression_s, etc., can also throw exceptions, so a more general term should be coined and applied in place of throw-expression wherever necessary.
Proposed resolution (February, 2012):
- Change 6.8.6.5.2 [basic.stc.dynamic.allocation] paragraph 3 as follows:
...Any other allocation function that fails to allocate storage shall indicate failure only by throwing an exception (14.2 [except.throw]) of a type that would match a handler (14.4 [except.handle]) of type std::bad_alloc (17.6.4.1 [bad.alloc]).
- Change 6.8.6.5.2 [basic.stc.dynamic.allocation] paragraph 4 as follows:
...[_Note:_ In particular, a global allocation function is not called to allocate storage for objects with static storage duration (6.8.6.2 [basic.stc.static]), for objects or references with thread storage duration (6.8.6.3 [basic.stc.thread]), for objects of typestd::type_info (7.6.1.8 [expr.typeid]), or for
the copy of an object thrown by a throw expressionan exception object (14.2 [except.throw]). —_end note_]
- Change 7.6.1.7 [expr.dynamic.cast] paragraph 9 as follows:
The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throwsan exception (14.2 [except.throw]) of a type that would match a handler (14.4 [except.handle]) of type std::bad_cast (17.7.4 [bad.cast]).
- Change 7.6.1.8 [expr.typeid] paragraph 2 as follows:
...If the glvalue expression is obtained by applying the unary* operator to a pointer68 and the pointer is a null pointer value (7.3.12 [conv.ptr]), the typeidexpression throws
thean exception (14.2 [except.throw]) of a type that would match a handler of type std::bad_typeid exception (17.7.5 [bad.typeid]).
- Change 7.6.2.8 [expr.new] paragraph 7 as follows:
When the value of the expression in a_noptr-new-declarator_ is zero, the allocation function is called to allocate an array with no elements. If the value of that_expression_ is less than zero or such that the size of the allocated object would exceed the implementation-defined limit, or if the_new-initializer_ is a braced-init-list for which the number of_initializer-clause_s exceeds the number of elements to initialize, no storage is obtained and the new-expression
terminates by throwingthrows an exception(14.2 [except.throw]) of a type that would match a handler (14.4 [except.handle]) of typestd::bad_array_new_length (17.6.4.2 [new.badlength]).
- Change Clause 14 [except] paragraph 1 as follows:
...A handler will be invoked only by
a _throw-expression_invokedthrowing an exception in code executed in the handler's try block or in functions called from the handler's try block...
- Change Clause 14 [except] paragraph 2 as follows:
A try-block is a statement (Clause 8 [stmt]). A throw-expression is of type void.
Code that executes a throw-expression is said to “throw an exception;” code that subsequently gets control is called a “handler.”[Note:...
- Change 14.2 [except.throw] paragraph 1 as follows:
Throwing an exception transfers control to a handler. [_Note:_An exception can be thrown from one of the following contexts:_throw-expression_ (see below), allocation functions (6.8.6.5.2 [basic.stc.dynamic.allocation]), dynamic_cast(7.6.1.7 [expr.dynamic.cast]), typeid (7.6.1.8 [expr.typeid]),new-expression (7.6.2.8 [expr.new]), and standard library functions (16.3.2.4 [structure.specifications]). —_end note_] An object is passed and the type of that object determines which handlers can catch it. [Example:...
- Change 14.2 [except.throw] paragraph 3 as follows:
A throw-expressionThrowing an exceptioncopy-initializes (9.5 [dcl.init], 11.4.5.3 [class.copy.ctor]) a temporary object, called the exception object, the type of which is determined by removing any top-level_cv-qualifier_s from the static type of the operand ofthrow and adjusting the type from “array ofT” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively. The temporary is an lvalue and is used to initialize the variable named in the matching_handler_ (14.4 [except.handle]). If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than (possibly cv-qualified) void the program is ill-formed.Except for these restrictions and the restrictions on type matching mentioned in 14.4 [except.handle], the operand of throw is treated exactly as a function argument in a call (7.6.1.3 [expr.call]) or the operand of a return statement.Evaluating a throw-expression with an operand throws an exception; the type of the exception object is determined by removing any top-level _cv-qualifier_s from the static type of the operand and adjusting the type from “array ofT” or “function returning T” to “pointer to T” or “pointer to function returning T,” respectively.
- Change 14.2 [except.throw] paragraph 4 as follows:
...[_Note:_
ana thrown exceptionthrown by a throw-expressiondoes not propagate to other threads unless caught, stored, and rethrown using appropriate library functions; see 17.9.7 [propagation] and 32.10 [futures]. —_end note_]
- Change 14.2 [except.throw] paragraph 8 as follows:
A throw-expression with no operand rethrows the currently handled exception (14.4 [except.handle]). The exception is reactivated with the existing
temporaryexception object; no newtemporaryexception object is created. The exception is no longer considered to be caught; therefore, the value of std::uncaught_exception() will again betrue. [Example:...
- Change 14.3 [except.ctor] paragraph 1 as follows:
As control passes from
a throw-expressionthe point where an exception is thrown to a handler, destructors are invoked for all automatic objects constructed since the try block was entered...
- Change 14.3 [except.ctor] paragraph 3 as follows:
The process of calling destructors for automatic objects constructed on the path from a try block to
a throw-expressionthe point where an exception is thrown is called “stack unwinding.” If a destructor...
- Change 14.4 [except.handle] paragraph 17 as follows:
When the handler declares
a non-constantanobject, any changes to that object will not affect thetemporary object that was initialized by execution of the_throw-expression_exception object. When the handler declares a reference toa non-constantan object, any changes to the referenced object are changes to thetemporary object initialized when the_throw-expression_ was executedexception objectand will have effect should that object be rethrown.
- Change 17.9.5.4 [terminate] paragraph 1 as follows:
Remarks: Called by the implementation when exception handling must be abandoned for any of several reasons (14.6.2 [except.terminate]), in effect immediately after
evaluating the_throw-expression_ (17.9.5.1 [terminate.handler])throwing the exception. May also be called directly by the program.