This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Voted into the WP at the November, 2010 meeting.]
N3092 comment GB 47The list of reasons for which std::terminate is called needs to be extended to cover several additional cases in C++0x:
when function std::nested_exception::rethrow_nested is called for an object that stores a null exception pointer.
when execution of a function registered with std::at_quick_exit exits using an exception.
when the destructor or a copy constructor of class std::thread is called for the object that is joinable.
Proposed resolution (August, 2010):
Change 14.6.2 [except.terminate] paragraph 1 as follows:
In
the followingsome situations exception handling must be abandoned for less subtle error handling techniques:. [Note: These situations are:
when the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught (14.2 [except.throw]), calls a function that exits via an
uncaughtexception,[Footnote: For example, if the object being thrown is of a class with a copy constructor, std::terminate() will be called if that copy constructor exits with an exception during a throw. —end footnote]orwhen the exception handling mechanism cannot find a handler for a thrown exception (14.4 [except.handle]), or
when the search for a handler (14.4 [except.handle]) encounters the outermost block of a function with a noexcept-specification that does not allow the exception (14.5 [except.spec]), or
when the destruction of an object during stack unwinding (15.2) terminates by throwing an exception, or
when initialization of a non-local variable with static or thread storage duration (6.9.3.2 [basic.start.static]
, 6.9.3.3 [basic.start.dynamic])terminates by throwingexits via an exception, orwhen destruction of an object with static or thread storage duration exits
usingvia an exception (6.9.3.3 [basic.start.dynamic]), orwhen execution of a function registered with std::atexit or std::at_quick_exit exits
usingvia an exception (17.5 [support.start.term]), orwhen a throw-expression with no operand attempts to rethrow an exception and no exception is being handled (14.2 [except.throw]), or
when std::unexpected throws an exception which is not allowed by the previously violated dynamic-exception-specification, and std::bad_exception is not included in that dynamic-exception-specification (_N4606_.15.5.2 [except.unexpected]), or
when the implementation's default unexpected exception handler is called (_N4606_.D.6.1 [unexpected.handler])
., orwhen the function std::nested_exception::rethrow_nested is called for an object that has captured no exception (17.9.8 [except.nested]), or
when execution of the initial function of a thread exits via an exception (33.4.3.3 [thread.thread.constr]), or
when the destructor or the copy assignment operator is invoked on a std::thread object that refers to a joinable thread (33.4.3.4 [thread.thread.destr], 33.4.3.5 [thread.thread.assign]).
—end note]
Insert the following as a new paragraph following 14.2 [except.throw] paragraph 6:
An exception is considered caught...
If the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught, calls a function that exits via an exception, std::terminate is called (14.6.2 [except.terminate]). [Example:
struct C { C() { } C(const C&) { throw 0; } }; int main() { try { throw C(); // calls std::terminate() } catch(C) { } }
—end example]
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-expression is called “stack unwinding.”[Note:If a destructor called during stack unwinding exits with an exception, std::terminate is called (14.6.2 [except.terminate]). [Note: So destructors should generally catch exceptions and not let them propagate out of the destructor. —end note]
Change 6.9.3.2 [basic.start.static] paragraph 6 as follows:
[Note:If the initialization of a non-local variable with static or thread storage durationterminates by throwingexits via an exception, std::terminate is called (see14.6.2 [except.terminate]).—end note]
Change 6.9.3.3 [basic.start.dynamic] paragraph 1 as follows:
...[Note:If the destruction ofa non-localan object with static or thread storage durationterminates by throwingexits via an exception, std::terminate is called (see14.6.2 [except.terminate]).—end note]
Change 17.5 [support.start.term] bullet 8.1 as follows:
First, objects with thread storage duration...
If control leaves a registered function called by exit because the function does not provide a handler for a thrown exception, terminate() shall be called (14.6.2 [except.terminate]).