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

567 lines
22 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.

[support.exception]
# 17 Language support library [[support]](./#support)
## 17.9 Exception handling [support.exception]
### [17.9.1](#general) General [[support.exception.general]](support.exception.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3843)
The header <exception> defines several types and functions related to the handling of exceptions in a C++ program[.](#general-1.sentence-1)
### [17.9.2](#exception.syn) Header <exception> synopsis [[exception.syn]](exception.syn)
// all freestandingnamespace std {class exception; class bad_exception; class nested_exception; using terminate_handler = void (*)();
terminate_handler get_terminate() noexcept;
terminate_handler set_terminate(terminate_handler f) noexcept; [[noreturn]] void terminate() noexcept; constexpr int uncaught_exceptions() noexcept; using exception_ptr = *unspecified*; constexpr exception_ptr current_exception() noexcept; [[noreturn]] constexpr void rethrow_exception(exception_ptr p); template<class E> constexpr exception_ptr make_exception_ptr(E e) noexcept; template<class E> constexpr const E* exception_ptr_cast(const exception_ptr& p) noexcept; template<class E> void exception_ptr_cast(const exception_ptr&&) = delete; template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t); template<class E> constexpr void rethrow_if_nested(const E& e);}
### [17.9.3](#exception) Class exception [[exception]](exception)
[🔗](#lib:exception)
namespace std {class exception {public:constexpr exception() noexcept; constexpr exception(const exception&) noexcept; constexpr exception& operator=(const exception&) noexcept; constexpr virtual ~exception(); constexpr virtual const char* what() const noexcept; };}
[1](#exception-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3893)
The classexception defines the base
class for the types of objects thrown as exceptions by
C++ standard library components, and certain
expressions, to report errors detected during program execution[.](#exception-1.sentence-1)
[2](#exception-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3901)
Except where explicitly specified otherwise,
each standard library class T that derives from class exception has the following publicly accessible member functions, each of them having
a non-throwing exception specification ([[except.spec]](except.spec "14.5Exception specifications")):
- [(2.1)](#exception-2.1)
default constructor (unless the class synopsis shows other constructors)
- [(2.2)](#exception-2.2)
copy constructor
- [(2.3)](#exception-2.3)
copy assignment operator
The copy constructor and the copy assignment operator meet
the following postcondition: If two objects lhs and rhs both have
dynamic type T and lhs is a copy of rhs, thenstrcmp(lhs.what(), rhs.what()) is equal to 0[.](#exception-2.sentence-1)
The what() member function of each such T satisfies the
constraints specified for exception::what() (see below)[.](#exception-2.sentence-2)
[🔗](#lib:exception,constructor_)
`constexpr exception(const exception& rhs) noexcept;
constexpr exception& operator=(const exception& rhs) noexcept;
`
[3](#exception-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3926)
*Postconditions*: If *this and rhs both have dynamic type exception then the value of the expression strcmp(what(), rhs.what()) shall equal 0[.](#exception-3.sentence-1)
[🔗](#lib:exception,destructor)
`constexpr virtual ~exception();
`
[4](#exception-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3938)
*Effects*: Destroys an object of classexception[.](#exception-4.sentence-1)
[🔗](#lib:what,exception)
`constexpr virtual const char* what() const noexcept;
`
[5](#exception-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3950)
*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3Character literals"))[.](#exception-5.sentence-1)
[6](#exception-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3956)
*Remarks*: The message may be a[null-terminated multibyte string](multibyte.strings#def:ntmbs "16.3.3.3.4.3Multibyte strings[multibyte.strings]"),
suitable for conversion and display as awstring ([[string.classes]](string.classes "27.4String classes"), [[locale.codecvt]](locale.codecvt "28.3.4.2.5Class template codecvt"))[.](#exception-6.sentence-1)
The return value remains valid until the exception object from which
it is obtained is destroyed or a non-const member function of the exception object is called[.](#exception-6.sentence-2)
### [17.9.4](#bad.exception) Class bad_exception [[bad.exception]](bad.exception)
[🔗](#lib:bad_exception)
namespace std {class bad_exception : public exception {public:// see [[exception]](#exception "17.9.3Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}
[1](#bad.exception-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3981)
The classbad_exception defines the type of the object
referenced by the exception_ptr returned from a call to current_exception ([[propagation]](#propagation "17.9.7Exception propagation"))
when the currently active exception object fails to copy[.](#bad.exception-1.sentence-1)
[🔗](#lib:what,bad_exception)
`constexpr const char* what() const noexcept override;
`
[2](#bad.exception-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L3995)
*Returns*: An implementation-defined ntbs[.](#bad.exception-2.sentence-1)
### [17.9.5](#exception.terminate) Abnormal termination [[exception.terminate]](exception.terminate)
#### [17.9.5.1](#terminate.handler) Type terminate_handler [[terminate.handler]](terminate.handler)
[🔗](#lib:terminate_handler)
`using terminate_handler = void (*)();
`
[1](#terminate.handler-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4010)
The type of a [*handler function*](#def:handler_function) to be invoked by terminatewhen terminating exception processing[.](#terminate.handler-1.sentence-1)
[2](#terminate.handler-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4016)
*Required behavior*: A terminate_handler shall
terminate execution of the program without returning to the caller[.](#terminate.handler-2.sentence-1)
[3](#terminate.handler-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4021)
*Default behavior*: The implementation's default terminate_handler callsabort()[.](#terminate.handler-3.sentence-1)
#### [17.9.5.2](#set.terminate) set_terminate [[set.terminate]](set.terminate)
[🔗](#lib:set_terminate)
`terminate_handler set_terminate(terminate_handler f) noexcept;
`
[1](#set.terminate-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4036)
*Effects*: Establishes the function designated by f as the current
handler function for terminating exception processing[.](#set.terminate-1.sentence-1)
[2](#set.terminate-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4041)
*Returns*: The previous terminate_handler[.](#set.terminate-2.sentence-1)
[3](#set.terminate-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4045)
*Remarks*: It is unspecified whether a null pointer value designates the defaultterminate_handler[.](#set.terminate-3.sentence-1)
#### [17.9.5.3](#get.terminate) get_terminate [[get.terminate]](get.terminate)
[🔗](#lib:get_terminate)
`terminate_handler get_terminate() noexcept;
`
[1](#get.terminate-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4059)
*Returns*: The current terminate_handler[.](#get.terminate-1.sentence-1)
[*Note [1](#get.terminate-note-1)*:
This can be a null pointer value[.](#get.terminate-1.sentence-2)
— *end note*]
#### [17.9.5.4](#terminate) terminate [[terminate]](terminate)
[🔗](#lib:terminate_)
`[[noreturn]] void terminate() noexcept;
`
[1](#terminate-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4075)
*Effects*: Calls a terminate_handler function[.](#terminate-1.sentence-1)
It is unspecified whichterminate_handler function will be called if an exception is active
during a call to set_terminate[.](#terminate-1.sentence-2)
Otherwise calls the current terminate_handler function[.](#terminate-1.sentence-3)
[*Note [1](#terminate-note-1)*:
A
default terminate_handler is always considered a callable handler in
this context[.](#terminate-1.sentence-4)
— *end note*]
[2](#terminate-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4087)
*Remarks*: Called by the implementation when exception
handling must be abandoned for any of several reasons ([[except.terminate]](except.terminate "14.6.2The std::terminate function"))[.](#terminate-2.sentence-1)
May also be called directly by the program[.](#terminate-2.sentence-2)
### [17.9.6](#uncaught.exceptions) uncaught_exceptions [[uncaught.exceptions]](uncaught.exceptions)
[🔗](#lib:uncaught_exceptions)
`constexpr int uncaught_exceptions() noexcept;
`
[1](#uncaught.exceptions-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4102)
*Returns*: The number of uncaught exceptions ([[except.throw]](except.throw "14.2Throwing an exception")) in the current thread[.](#uncaught.exceptions-1.sentence-1)
[2](#uncaught.exceptions-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4106)
*Remarks*: When uncaught_exceptions() > 0,
throwing an exception can result in a call of the function[std::terminate](except.terminate "14.6.2The std::terminate function[except.terminate]")[.](#uncaught.exceptions-2.sentence-1)
### [17.9.7](#propagation) Exception propagation [[propagation]](propagation)
[🔗](#lib:exception_ptr)
`using exception_ptr = unspecified;
`
[1](#propagation-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4121)
The type exception_ptr can be used to refer to an exception object[.](#propagation-1.sentence-1)
[2](#propagation-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4124)
exception_ptr meets the requirements of[*Cpp17NullablePointer*](nullablepointer.requirements#:Cpp17NullablePointer "16.4.4.4Cpp17NullablePointer requirements[nullablepointer.requirements]") (Table [36](nullablepointer.requirements#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements"))[.](#propagation-2.sentence-1)
[3](#propagation-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4128)
Two non-null values of type exception_ptr are equivalent and compare equal if and
only if they refer to the same exception[.](#propagation-3.sentence-1)
[4](#propagation-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4132)
The default constructor of exception_ptr produces the null value of the
type[.](#propagation-4.sentence-1)
[5](#propagation-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4136)
exception_ptr shall not be implicitly convertible to any arithmetic,
enumeration, or pointer type[.](#propagation-5.sentence-1)
[6](#propagation-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4140)
[*Note [1](#propagation-note-1)*:
An implementation can use a reference-counted smart
pointer as exception_ptr[.](#propagation-6.sentence-1)
— *end note*]
[7](#propagation-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4146)
For purposes of determining the presence of a data race, operations onexception_ptr objects shall access and modify only theexception_ptr objects themselves and not the exceptions they refer to[.](#propagation-7.sentence-1)
Use of rethrow_exception or exception_ptr_cast on exception_ptr objects that refer to
the same exception object shall not introduce a data race[.](#propagation-7.sentence-2)
[*Note [2](#propagation-note-2)*:
Ifrethrow_exception rethrows the same exception object (rather than a copy),
concurrent access to that rethrown exception object can introduce a data race[.](#propagation-7.sentence-3)
Changes in the number of exception_ptr objects that refer to a
particular exception do not introduce a data race[.](#propagation-7.sentence-4)
— *end note*]
[8](#propagation-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4161)
All member functions are marked constexpr[.](#propagation-8.sentence-1)
[🔗](#lib:current_exception)
`constexpr exception_ptr current_exception() noexcept;
`
[9](#propagation-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4171)
*Returns*: An exception_ptr object that refers to the[currently handled exception](except.handle#def:exception_handling,currently_handled_exception "14.4Handling an exception[except.handle]") or a copy of the currently
handled exception, or a null exception_ptr object if no exception is being
handled[.](#propagation-9.sentence-1)
The referenced object shall remain valid at least as long as there is anexception_ptr object that refers to it[.](#propagation-9.sentence-2)
If the function needs to allocate memory and the attempt fails, it returns anexception_ptr object that refers to an instance of bad_alloc[.](#propagation-9.sentence-3)
It is unspecified whether the return values of two successive calls tocurrent_exception refer to the same exception object[.](#propagation-9.sentence-4)
[*Note [3](#propagation-note-3)*:
That is, it is unspecified whether current_exception creates a new copy each time it is called[.](#propagation-9.sentence-5)
— *end note*]
If the attempt to copy the current exception object throws an exception, the function
returns an exception_ptr object that refers to the thrown exception or,
if this is not possible, to an instance of bad_exception[.](#propagation-9.sentence-6)
[*Note [4](#propagation-note-4)*:
The copy constructor of the thrown exception can also fail,
so the implementation can substitute a bad_exception object
to avoid infinite recursion[.](#propagation-9.sentence-7)
— *end note*]
[🔗](#lib:rethrow_exception)
`[[noreturn]] constexpr void rethrow_exception(exception_ptr p);
`
[10](#propagation-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4203)
*Preconditions*: p is not a null pointer[.](#propagation-10.sentence-1)
[11](#propagation-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4207)
*Effects*: Let u be the exception object to which p refers, or
a copy of that exception object[.](#propagation-11.sentence-1)
It is unspecified whether a copy is made, and
memory for the copy is allocated in an unspecified way[.](#propagation-11.sentence-2)
- [(11.1)](#propagation-11.1)
If allocating memory to form u fails,
throws an instance of bad_alloc;
- [(11.2)](#propagation-11.2)
otherwise, if copying the exception to which p refers
to form u throws an exception, throws that exception;
- [(11.3)](#propagation-11.3)
otherwise, throws u.
[🔗](#lib:make_exception_ptr)
`template<class E> constexpr exception_ptr make_exception_ptr(E e) noexcept;
`
[12](#propagation-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4231)
*Effects*: Creates an exception_ptr object that refers to a copy of e, as if:try {throw e;} catch(...) {return current_exception();}
[13](#propagation-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4242)
[*Note [5](#propagation-note-5)*:
This function is provided for convenience and
efficiency reasons[.](#propagation-13.sentence-1)
— *end note*]
[🔗](#lib:exception_ptr_cast)
`template<class E> constexpr const E* exception_ptr_cast(const exception_ptr& p) noexcept;
`
[14](#propagation-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4255)
*Mandates*: E is a cv-unqualified complete object type[.](#propagation-14.sentence-1)
E is not an array type[.](#propagation-14.sentence-2)
E is not a pointer or pointer-to-member type[.](#propagation-14.sentence-3)
[*Note [6](#propagation-note-6)*:
When E is a pointer or pointer-to-member type,
a handler of type const E& can match
without binding to the exception object itself[.](#propagation-14.sentence-4)
— *end note*]
[15](#propagation-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4266)
*Returns*: A pointer to the exception object referred to by p,
if p is not null and
a handler of type const E& would be a match ([[except.handle]](except.handle "14.4Handling an exception")) for that exception object[.](#propagation-15.sentence-1)
Otherwise, nullptr[.](#propagation-15.sentence-2)
### [17.9.8](#except.nested) nested_exception [[except.nested]](except.nested)
[🔗](#lib:nested_exception)
namespace std {class nested_exception {public:constexpr nested_exception() noexcept; constexpr nested_exception(const nested_exception&) noexcept = default; constexpr nested_exception& operator=(const nested_exception&) noexcept = default; constexpr virtual ~nested_exception() = default; // access functions[[noreturn]] constexpr void rethrow_nested() const; constexpr exception_ptr nested_ptr() const noexcept; }; template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t); template<class E> constexpr void rethrow_if_nested(const E& e);}
[1](#except.nested-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4297)
The class nested_exception is designed for use as a mixin through
multiple inheritance[.](#except.nested-1.sentence-1)
It captures the currently handled exception and stores it
for later use[.](#except.nested-1.sentence-2)
[2](#except.nested-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4302)
[*Note [1](#except.nested-note-1)*:
nested_exception has a virtual destructor to make it a
polymorphic class[.](#except.nested-2.sentence-1)
Its presence can be tested for with dynamic_cast[.](#except.nested-2.sentence-2)
— *end note*]
[🔗](#lib:nested_exception,constructor)
`constexpr nested_exception() noexcept;
`
[3](#except.nested-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4314)
*Effects*: The constructor calls current_exception() and stores the returned value[.](#except.nested-3.sentence-1)
[🔗](#lib:rethrow_nested,nested_exception)
`[[noreturn]] constexpr void rethrow_nested() const;
`
[4](#except.nested-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4325)
*Effects*: If nested_ptr() returns a null pointer, the function calls the function std::terminate[.](#except.nested-4.sentence-1)
Otherwise, it throws the stored exception captured by *this[.](#except.nested-4.sentence-2)
[🔗](#lib:nested_ptr,nested_exception)
`constexpr exception_ptr nested_ptr() const noexcept;
`
[5](#except.nested-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4337)
*Returns*: The stored exception captured by this nested_exception object[.](#except.nested-5.sentence-1)
[🔗](#lib:throw_with_nested,nested_exception)
`template<class T> [[noreturn]] constexpr void throw_with_nested(T&& t);
`
[6](#except.nested-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4348)
Let U be decay_t<T>[.](#except.nested-6.sentence-1)
[7](#except.nested-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4351)
*Preconditions*: U meets the [*Cpp17CopyConstructible*](utility.arg.requirements#:Cpp17CopyConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") requirements[.](#except.nested-7.sentence-1)
[8](#except.nested-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4355)
*Throws*: If is_class_v<U> && !is_final_v<U> && !is_base_of_v<nested_exception, U> is true,
an exception of unspecified type that is publicly derived from bothU and nested_exception and constructed from std::forward<T>(t), otherwisestd::forward<T>(t)[.](#except.nested-8.sentence-1)
[🔗](#lib:rethrow_if_nested,nested_exception)
`template<class E> constexpr void rethrow_if_nested(const E& e);
`
[9](#except.nested-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/support.tex#L4371)
*Effects*: If E is not a polymorphic class type, or
if nested_exception is an inaccessible or ambiguous base class of E,
there is no effect[.](#except.nested-9.sentence-1)
Otherwise, performs:if (auto p = dynamic_cast<const nested_exception*>(addressof(e))) p->rethrow_nested();