[except.throw] (original) (raw)

14 Exception handling [except]

14.2 Throwing an exception [except.throw]

Throwing an exception transfers control to a handler.

An object is passed and the type of that object determines which handlers can catch it.

[Example 1:

throw "Help!";can be caught by ahandlerofconst char*type:try { } catch(const char* p) { } andclass Overflow { public: Overflow(char,double,double);};void f(double x) { throw Overflow('+',x,3.45e107);} can be caught by a handler for exceptions of typeOverflow:try { f(1.2);} catch(Overflow& oo) { }

— _end example_]

When an exception is thrown, control is transferred to the nearest handler with a matching type ([except.handle]); “nearest” means the handler for which thecompound-statement orctor-initializerfollowing thetrykeyword was most recently entered by the thread of control and not yet exited.

An lvalue denoting the temporary is used to initialize the variable declared in the matchinghandler ([except.handle]).

If the type of the exception object would be an incomplete type, an abstract class type ([class.abstract]), or a pointer to an incomplete type other than cv voidthe program is ill-formed.

The memory for the exception object is allocated in an unspecified way, except as noted in [basic.stc.dynamic.allocation].

If a handler exits by rethrowing, control is passed to another handler for the same exception object.

The points of potential destruction for the exception object are:

Among all points of potential destruction for the exception object, there is an unspecified last one where the exception object is destroyed.

[Note 2:

No other thread synchronization is implied in exception handling.

— _end note_]

The implementation may then deallocate the memory for the exception object; any such deallocation is done in an unspecified way.

[Note 3:

A thrown exception does not propagate to other threads unless caught, stored, and rethrown using appropriate library functions; see [propagation] and [futures].

— _end note_]

When the thrown object is a class object, the constructor selected for the copy-initialization as well as the constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted and accessible, even if the copy/move operation is elided ([class.copy.elision]).

The destructor is potentially invoked ([class.dtor]).

An exception is considered caught when a handler for that exception becomes active.

[Note 4:

An exception can have active handlers and still be considered uncaught if it is rethrown.

— _end note_]

If the exception handling mechanism handling an uncaught exceptiondirectly invokes a function that exits via an exception, the function std​::​terminate is called.

[Example 2: struct C { C() { } C(const C&) { if (std::uncaught_exceptions()) { throw 0; } } };int main() { try { throw C(); } catch(C) { } } — _end example_]

[Note 5:

If a destructor directly invoked by stack unwinding exits via an exception,std​::​terminate is invoked.

— _end note_]