Files
cppdraft_translate/cppdraft/except/throw.md
2025-10-25 03:02:53 +03:00

177 lines
8.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.18Throwing an exception[expr.throw]")*s* ([[expr.throw]](expr.throw "7.6.18Throwing an exception")),
allocation functions ([[basic.stc.dynamic.allocation]](basic.stc.dynamic.allocation "6.8.6.5.2Allocation functions")),dynamic_cast ([[expr.dynamic.cast]](expr.dynamic.cast "7.6.1.7Dynamic cast")),typeid ([[expr.typeid]](expr.typeid "7.6.1.8Type identification")),[*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]")*s* ([[expr.new]](expr.new "7.6.2.8New")), and standard library
functions ([[structure.specifications]](structure.specifications "16.3.2.4Detailed 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.1Preamble[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.4Handling an exception")); “nearest” means the handler
for which the[*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") or[*ctor-initializer*](class.base.init#nt:ctor-initializer "11.9.3Initializing 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.2Throwing 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.1General")),
an abstract class type ([[class.abstract]](class.abstract "11.7.4Abstract classes")),
or a pointer to an incomplete type other thancv void ([[basic.compound]](basic.compound "6.9.4Compound 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.2Allocation 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.1Preamble[except.pre]") in the handler;
- [(4.2)](#4.2)
when an object of type [std::exception_ptr](propagation#lib:exception_ptr "17.9.7Exception 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.2Data 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.7Exception propagation") and [[futures]](futures "32.10Futures")[.](#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.3One-definition rule")) and
the destructor of T is potentially invoked ([[class.dtor]](class.dtor "11.4.7Destructors"))[.](#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.2Throwing 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.4Handling 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.18Throwing an exception"), [[propagation]](propagation "17.9.7Exception 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.6uncaught_­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.4Handling 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.2The 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.1Preamble[except.pre]") object ([[except.handle]](except.handle "14.4Handling an exception"))}}};
int main() {try {throw C(); // calls std::terminate if construction of the handler's// [*exception-declaration*](except.pre#nt:exception-declaration "14.1Preamble[except.pre]") object is not elided ([[class.copy.elision]](class.copy.elision "11.9.6Copy/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*]