Title
Additional reasons to call std::terminate
Status
c++11
Section
14.6.2 [except.terminate]
Submitter
GB

Created on 2010-08-03.00:00:00 last changed 123 months ago

Messages

Date: 2010-11-15.00:00:00

[Voted into the WP at the November, 2010 meeting.]

Date: 2010-08-15.00:00:00

Proposed resolution (August, 2010):

  1. Change 14.6.2 [except.terminate] paragraph 1 as follows:

  2. In the following some 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 uncaught exception, [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] or

    • when 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 throwing exits via an exception, or

    • when destruction of an object with static or thread storage duration exits using via an exception (6.9.3.3 [basic.start.dynamic]), or

    • when execution of a function registered with std::atexit or std::at_quick_exit exits using via an exception (17.5 [support.start.term]), or

    • when 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])., or

    • when 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]

  3. Insert the following as a new paragraph following 14.2 [except.throw] paragraph 6:

  4. 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]

  5. Change 14.3 [except.ctor] paragraph 3 as follows:

  6. 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]
  7. Change 6.9.3.2 [basic.start.static] paragraph 6 as follows:

  8. [Note: If the initialization of a non-local variable with static or thread storage duration terminates by throwing exits via an exception, std::terminate is called (see 14.6.2 [except.terminate]). end note]
  9. Change 6.9.3.3 [basic.start.dynamic] paragraph 1 as follows:

  10. ...[Note: If the destruction of a non-local an object with static or thread storage duration terminates by throwing exits via an exception, std::terminate is called (see 14.6.2 [except.terminate]). end note]
  11. 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]).

Date: 2010-08-03.00:00:00
N3092 comment GB 47

The 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.

History
Date User Action Args
2014-03-03 00:00:00adminsetstatus: fdis -> c++11
2011-04-10 00:00:00adminsetstatus: dr -> fdis
2010-11-29 00:00:00adminsetmessages: + msg3208
2010-11-29 00:00:00adminsetstatus: ready -> dr
2010-08-23 00:00:00adminsetmessages: + msg2819
2010-08-03 00:00:00admincreate