The function std::terminate() is used by the exception handling mechanism for coping with errors related to the exception handling mechanism itself. The function std::current_exception() and the class std::nested_exception can be used by a program to capture the currently handled exception.
In some situations exception handling must be abandoned for less subtle error handling techniques. [ Note: These situations are:
when the exception handling mechanism, after completing the initialization of the exception object but before activation of a handler for the exception ([except.throw]), calls a function that exits via an exception, or
when the exception handling mechanism cannot find a handler for a thrown exception ([except.handle]), or
when the search for a handler encounters the outermost block of a function with a non-throwing exception specification, or
when the destruction of an object during stack unwinding terminates by throwing an exception, or
when initialization of a non-local variable with static or thread storage duration ([basic.start.dynamic]) exits via an exception, or
when destruction of an object with static or thread storage duration exits via an exception ([basic.start.term]), or
when execution of a function registered with std::atexit or std::at_quick_exit exits via an exception ([support.start.term]), or
when a throw-expression with no operand attempts to rethrow an exception and no exception is being handled ([except.throw]), or
when the function std::nested_exception::rethrow_nested is called for an object that has captured no exception ([except.nested]), or
when execution of the initial function of a thread exits via an exception ([thread.thread.constr]), or
for a parallel algorithm whose ExecutionPolicy specifies such behavior ([execpol.seq], [execpol.par], [execpol.parunseq]), when execution of an element access function ([algorithms.parallel.defns]) of the parallel algorithm exits via an exception ([algorithms.parallel.exceptions]), or
when the destructor or the copy assignment operator is invoked on an object of type std::thread that refers to a joinable thread ([thread.thread.destr], [thread.thread.assign]), or
when a call to a wait(), wait_until(), or wait_for() function on a condition variable ([thread.condition.condvar], [thread.condition.condvarany]) fails to meet a postcondition.
— end note ]
In such cases, std::terminate() is called. In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called. In the situation where the search for a handler encounters the outermost block of a function with a non-throwing exception specification, it is implementation-defined whether the stack is unwound, unwound partially, or not unwound at all before std::terminate() is called. In all other situations, the stack shall not be unwound before std::terminate() is called. An implementation is not permitted to finish stack unwinding prematurely based on a determination that the unwind process will eventually cause a call to std::terminate().
An exception is considered uncaught after completing the initialization of the exception object until completing the activation of a handler for the exception ([except.handle]). This includes stack unwinding. If an exception is rethrown ([expr.throw], [propagation]), it is considered uncaught from the point of rethrow until the rethrown exception is caught. The function std::uncaught_exceptions() returns the number of uncaught exceptions in the current thread.