[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)
