[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*]