[except.throw]

# 14 Exception handling [[except]](./#except)

## 14.2 Throwing an exception [except.throw]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L192)

Throwing an exception transfers control to a handler[.](#1.sentence-1)

[*Note [1](#note-1)*:

An exception can be thrown from one of the following contexts:[*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]")*s* ([[expr.throw]](expr.throw "7.6.18 Throwing an exception")),
allocation functions ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions")),dynamic_cast ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7 Dynamic cast")),typeid ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")),[*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8 New")), and standard library
functions ([[structure.specifications]](structure.specifications "16.3.2.4 Detailed specifications"))[.](#1.sentence-2)

â *end note*]

An object is passed and the type of that object determines which handlers
can catch it[.](#1.sentence-3)

[*Example [1](#example-1)*:

throw "Help!"; can be caught by a[*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") ofconstchar* type:try {// ...} catch(const char* p) {// handle character string exceptions here} 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) {// handle exceptions of type Overflow here}

â *end example*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L244)

When an exception is thrown, control is transferred to the nearest handler with
a matching type ([[except.handle]](except.handle "14.4 Handling an exception")); ânearestâ means the handler
for which the[*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") or[*ctor-initializer*](class.base.init#nt:ctor-initializer "11.9.3 Initializing bases and members [class.base.init]") following thetry keyword was most recently entered by the thread of control and not yet exited[.](#2.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L257)

Throwing an exception
initializes an object with dynamic storage duration,
called the[*exception object*](#def:exception_handling,exception_object "14.2 Throwing an exception [except.throw]")[.](#3.sentence-1)

If the type of the exception object would be
an incomplete type ([[basic.types.general]](basic.types.general "6.9.1 General")),
an abstract class type ([[class.abstract]](class.abstract "11.7.4 Abstract classes")),
or a pointer to an incomplete type other thancv void ([[basic.compound]](basic.compound "6.9.4 Compound types")),
the program is ill-formed[.](#3.sentence-2)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L269)

The memory for the exception object is
allocated in an unspecified way, except as noted in [[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2 Allocation functions")[.](#4.sentence-1)

If a handler exits by rethrowing, control is passed to another handler for
the same exception object[.](#4.sentence-2)

The points of potential destruction for the exception object are:

- [(4.1)](#4.1)

when an active handler for the exception exits by
any means other than
rethrowing,
immediately after the destruction of the object (if any)
declared in the [*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") in the handler;

- [(4.2)](#4.2)

when an object of type [std​::​exception_ptr](propagation#lib:exception_ptr "17.9.7 Exception propagation [propagation]") that refers to the exception object is destroyed,
before the destructor of std​::​exception_ptr returns[.](#4.sentence-3)

Among all points of potential destruction for the exception object,
there is an unspecified last one
where the exception object is destroyed[.](#4.sentence-4)

All other points [happen before](intro.races#def:happens_before "6.10.2.2 Data races [intro.races]") that last one[.](#4.sentence-5)

[*Note [2](#note-2)*:

No other thread synchronization is implied in exception handling[.](#4.sentence-6)

â *end note*]

The implementation may then
deallocate the memory for the exception object; any such deallocation
is done in an unspecified way[.](#4.sentence-7)

[*Note [3](#note-3)*:

A thrown exception does not
propagate to other threads unless caught, stored, and rethrown using
appropriate library functions; see [[propagation]](propagation "17.9.7 Exception propagation") and [[futures]](futures "32.10 Futures")[.](#4.sentence-8)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L308)

Let T denote the type of the exception object[.](#5.sentence-1)

Copy-initialization of an object of type T from
an lvalue of type const T in a context unrelated to T shall be well-formed[.](#5.sentence-2)

If T is a class type,
the selected constructor is odr-used ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule")) and
the destructor of T is potentially invoked ([[class.dtor]](class.dtor "11.4.7 Destructors"))[.](#5.sentence-3)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L319)

An exception is considered [*uncaught*](#def:uncaught_exception "14.2 Throwing an exception [except.throw]") after completing the initialization of the exception object
until completing the activation of a handler for the exception ([[except.handle]](except.handle "14.4 Handling an exception"))[.](#6.sentence-1)

[*Note [4](#note-4)*:

As a consequence, an exception is considered uncaught
during any stack unwinding resulting from it being thrown[.](#6.sentence-2)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L329)

If an exception is rethrown ([[expr.throw]](expr.throw "7.6.18 Throwing an exception"), [[propagation]](propagation "17.9.7 Exception propagation")),
it is considered uncaught from the point of rethrow
until the rethrown exception is caught[.](#7.sentence-1)

[*Note [5](#note-5)*:

The function std​::​uncaught_exceptions ([[uncaught.exceptions]](uncaught.exceptions "17.9.6 uncaught_­exceptions"))
returns the number of uncaught exceptions in the current thread[.](#7.sentence-2)

â *end note*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L339)

An exception is considered caught when a handler for that exception
becomes [active](except.handle#def:exception_handling,handler,active "14.4 Handling an exception [except.handle]")[.](#8.sentence-1)

[*Note [6](#note-6)*:

An exception can have active handlers and still be considered uncaught if
it is rethrown[.](#8.sentence-2)

â *end note*]

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L349)

If the exception handling mechanism
handling an uncaught exception
directly invokes a function that exits via an
exception, the function [std​::​terminate](except.terminate "14.6.2 The std​::​terminate function [except.terminate]") is invoked[.](#9.sentence-1)

[*Example [2](#example-2)*: struct C { C() { } C(const C&) {if (std::uncaught_exceptions()) {throw 0; // throw during copy to handler's [*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") object ([[except.handle]](except.handle "14.4 Handling an exception"))}}};

int main() {try {throw C(); // calls std​::​terminate if construction of the handler's// [*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") object is not elided ([[class.copy.elision]](class.copy.elision "11.9.6 Copy/move elision"))} catch(C) { }} â *end example*]

[*Note [7](#note-7)*:

If a destructor directly invoked by stack unwinding exits via an exception,std​::​terminate is invoked[.](#9.sentence-2)

â *end note*]
