[except.handle] # 14 Exception handling [[except]](./#except) ## 14.4 Handling an exception [except.handle] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L500) The[*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") in a[*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") describes the type(s) of exceptions that can cause that[*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") to be entered[.](#1.sentence-1) The[*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") shall not denote an incomplete type, an abstract class type, or an rvalue reference type[.](#1.sentence-2) The[*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") shall not denote a pointer or reference to an incomplete type, other than “pointer to cv void”[.](#1.sentence-3) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L521) A handler of type“array of T” orfunction type T is adjusted to be of type “pointer to T”[.](#2.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L530) A[*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") is a match for an exception object of typeE if - [(3.1)](#3.1) The [*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") is of type cv T orcv T& andE and T are the same type (ignoring the top-level [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s*), or - [(3.2)](#3.2) the [*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") is of type cv T orcv T& andT is an unambiguous public base class of E, or - [(3.3)](#3.3) the [*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") is of type cv T or const T& where T is a pointer or pointer-to-member type andE is a pointer or pointer-to-member type that can be converted to T by one or more of * [(3.3.1)](#3.3.1) a standard [pointer conversion](conv.ptr "7.3.12 Pointer conversions [conv.ptr]") not involving conversions to pointers to private or protected or ambiguous classes * [(3.3.2)](#3.3.2) a [function pointer conversion](conv.fctptr "7.3.14 Function pointer conversions [conv.fctptr]") * [(3.3.3)](#3.3.3) a [qualification conversion](conv.qual "7.3.6 Qualification conversions [conv.qual]"), or - [(3.4)](#3.4) the [*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") is of type cv T or const T& where T is a pointer or pointer-to-member type and E is std​::​nullptr_t[.](#3.sentence-1) [*Note [1](#note-1)*: A[*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]") whose operand is an integer literal with value zero does not match a handler of pointer or pointer-to-member type[.](#3.sentence-2) A handler of reference to array or function type is never a match for any exception object ([[expr.throw]](expr.throw "7.6.18 Throwing an exception"))[.](#3.sentence-3) — *end note*] [*Example [1](#example-1)*: class Matherr { /* ... */ virtual void vf(); };class Overflow: public Matherr { /* ... */ };class Underflow: public Matherr { /* ... */ };class Zerodivide: public Matherr { /* ... */ }; void f() {try { g(); } catch (Overflow oo) {// ...} catch (Matherr mm) {// ...}} Here, theOverflow handler will catch exceptions of typeOverflow and theMatherr handler will catch exceptions of typeMatherr and of all types publicly derived fromMatherr including exceptions of typeUnderflow andZerodivide[.](#3.sentence-4) — *end example*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L611) The handlers for a try block are tried in order of appearance[.](#4.sentence-1) [*Note [2](#note-2)*: This makes it possible to write handlers that can never be executed, for example by placing a handler for a final derived class after a handler for a corresponding unambiguous public base class[.](#4.sentence-2) — *end note*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L619) A... in a handler's[*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]") specifies a match for any exception[.](#5.sentence-1) If present, a... handler shall be the last handler for its try block[.](#5.sentence-2) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L629) If no match is found among the handlers for a try block, the search for a matching handler continues in a dynamically surrounding try block of the same thread[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L635) If the search for a handler exits the function body of a function with a non-throwing exception specification, the function std​::​terminate ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function")) is invoked[.](#7.sentence-1) [*Note [3](#note-3)*: An implementation is not permitted to reject an expression merely because, when executed, it throws or might throw an exception from a function with a non-throwing exception specification[.](#7.sentence-2) — *end note*] [*Example [2](#example-2)*: extern void f(); // potentially-throwingvoid g() noexcept { f(); // valid, even if f throwsthrow 42; // valid, effectively a call to std​::​terminate} The call tof is well-formed despite the possibility for it to throw an exception[.](#7.sentence-3) — *end example*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L661) If no matching handler is found, the function std​::​terminate is invoked; whether or not the stack is unwound before this invocation ofstd​::​terminate is implementation-defined ([[except.terminate]](except.terminate "14.6.2 The std​::​terminate function"))[.](#8.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L669) A handler is considered [*active*](#def:exception_handling,handler,active "14.4 Handling an exception [except.handle]") when initialization is complete for the parameter (if any) of the catch clause[.](#9.sentence-1) [*Note [4](#note-4)*: The stack will have been unwound at that point[.](#9.sentence-2) — *end note*] Also, an implicit handler is considered active when the function std​::​terminate is entered due to a throw[.](#9.sentence-3) A handler is no longer considered active when the catch clause exits[.](#9.sentence-4) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L680) The exception with the most recently activated handler that is still active is called the[*currently handled exception*](#def:exception_handling,currently_handled_exception "14.4 Handling an exception [except.handle]")[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L686) Referring to any non-static member or base class of an object in the handler for a[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") of a constructor or destructor for that object results in undefined behavior[.](#11.sentence-1) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L692) Exceptions thrown in destructors of objects with static storage duration or in constructors of objects associated with non-block variables with static storage duration are not caught by a[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") on the [main function](basic.start.main "6.10.3.1 main function [basic.start.main]")[.](#12.sentence-1) Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") on the initial function of the thread[.](#12.sentence-2) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L702) If a return statement ([[stmt.return]](stmt.return "8.8.4 The return statement")) appears in a handler of the[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") of a constructor, the program is ill-formed[.](#13.sentence-1) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L708) The currently handled exception is rethrown if control reaches the end of a handler of the[*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") of a constructor or destructor[.](#14.sentence-1) Otherwise, flowing off the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of a [*handler*](except.pre#nt:handler "14.1 Preamble [except.pre]") of a [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]") is equivalent to flowing off the end of the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of that function (see [[stmt.return]](stmt.return "8.8.4 The return statement"))[.](#14.sentence-2) [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L721) The variable declared by the [*exception-declaration*](except.pre#nt:exception-declaration "14.1 Preamble [except.pre]"), of typecv T or cv T&, is initialized from the exception object, of type E, as follows: - [(15.1)](#15.1) if T is a base class of E, the variable is copy-initialized ([[dcl.init]](dcl.init "9.5 Initializers")) from an lvalue of type T designating the corresponding base class subobject of the exception object; - [(15.2)](#15.2) otherwise, the variable is copy-initialized ([[dcl.init]](dcl.init "9.5 Initializers")) from an lvalue of type E designating the exception object[.](#15.sentence-1) The lifetime of the variable ends when the handler exits, after the destruction of any objects with automatic storage duration initialized within the handler[.](#15.sentence-2) [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exceptions.tex#L740) When the handler declares an object, any changes to that object will not affect the exception object[.](#16.sentence-1) When the handler declares a reference to an object, any changes to the referenced object are changes to the exception object and will have effect should that object be rethrown[.](#16.sentence-2)