- tmp/tmpvjdnrrqp/{from.md → to.md} +133 -101
tmp/tmpvjdnrrqp/{from.md → to.md}
RENAMED
|
@@ -183,15 +183,15 @@ When an exception is thrown, control is transferred to the nearest
|
|
| 183 |
handler with a matching type [[except.handle]]; “nearest” means the
|
| 184 |
handler for which the *compound-statement* or *ctor-initializer*
|
| 185 |
following the `try` keyword was most recently entered by the thread of
|
| 186 |
control and not yet exited.
|
| 187 |
|
| 188 |
-
Throwing an exception
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
[[class.abstract]], or a pointer to an incomplete type other
|
| 192 |
-
cv `void` the program is ill-formed.
|
| 193 |
|
| 194 |
The memory for the exception object is allocated in an unspecified way,
|
| 195 |
except as noted in [[basic.stc.dynamic.allocation]]. If a handler exits
|
| 196 |
by rethrowing, control is passed to another handler for the same
|
| 197 |
exception object. The points of potential destruction for the exception
|
|
@@ -216,27 +216,40 @@ object; any such deallocation is done in an unspecified way.
|
|
| 216 |
|
| 217 |
[*Note 3*: A thrown exception does not propagate to other threads
|
| 218 |
unless caught, stored, and rethrown using appropriate library functions;
|
| 219 |
see [[propagation]] and [[futures]]. — *end note*]
|
| 220 |
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
[[class.
|
| 226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
|
| 228 |
An exception is considered caught when a handler for that exception
|
| 229 |
becomes active [[except.handle]].
|
| 230 |
|
| 231 |
-
[*Note
|
| 232 |
considered uncaught if it is rethrown. — *end note*]
|
| 233 |
|
| 234 |
If the exception handling mechanism handling an uncaught exception
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
[[except.terminate]].
|
| 238 |
|
| 239 |
[*Example 2*:
|
| 240 |
|
| 241 |
``` cpp
|
| 242 |
struct C {
|
|
@@ -256,14 +269,14 @@ int main() {
|
|
| 256 |
}
|
| 257 |
```
|
| 258 |
|
| 259 |
— *end example*]
|
| 260 |
|
| 261 |
-
[*Note
|
| 262 |
via an exception, `std::terminate` is invoked. — *end note*]
|
| 263 |
|
| 264 |
-
##
|
| 265 |
|
| 266 |
As control passes from the point where an exception is thrown to a
|
| 267 |
handler, objects are destroyed by a process, specified in this
|
| 268 |
subclause, called *stack unwinding*.
|
| 269 |
|
|
@@ -309,12 +322,12 @@ initialization and whose initialization has completed [[dcl.init]].
|
|
| 309 |
[*Note 1*: If such an object has a reference member that extends the
|
| 310 |
lifetime of a temporary object, this ends the lifetime of the reference
|
| 311 |
member, so the lifetime of the temporary object is effectively not
|
| 312 |
extended. — *end note*]
|
| 313 |
|
| 314 |
-
A subobject is *known to be initialized* if
|
| 315 |
-
specified
|
| 316 |
|
| 317 |
- in [[class.base.init]] for initialization by constructor,
|
| 318 |
- in [[class.copy.ctor]] for initialization by defaulted copy/move
|
| 319 |
constructor,
|
| 320 |
- in [[class.inhctor.init]] for initialization by inherited constructor,
|
|
@@ -418,36 +431,60 @@ The handlers for a try block are tried in order of appearance.
|
|
| 418 |
[*Note 2*: This makes it possible to write handlers that can never be
|
| 419 |
executed, for example by placing a handler for a final derived class
|
| 420 |
after a handler for a corresponding unambiguous public base
|
| 421 |
class. — *end note*]
|
| 422 |
|
| 423 |
-
A `...` in a handler’s *exception-declaration*
|
| 424 |
-
`...` in a function parameter declaration; it specifies a match for any
|
| 425 |
exception. If present, a `...` handler shall be the last handler for its
|
| 426 |
try block.
|
| 427 |
|
| 428 |
If no match is found among the handlers for a try block, the search for
|
| 429 |
a matching handler continues in a dynamically surrounding try block of
|
| 430 |
the same thread.
|
| 431 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
A handler is considered *active* when initialization is complete for the
|
| 433 |
parameter (if any) of the catch clause.
|
| 434 |
|
| 435 |
-
[*Note
|
| 436 |
point. — *end note*]
|
| 437 |
|
| 438 |
Also, an implicit handler is considered active when the function
|
| 439 |
`std::terminate` is entered due to a throw. A handler is no longer
|
| 440 |
considered active when the catch clause exits.
|
| 441 |
|
| 442 |
The exception with the most recently activated handler that is still
|
| 443 |
active is called the *currently handled exception*.
|
| 444 |
|
| 445 |
-
If no matching handler is found, the function `std::terminate` is
|
| 446 |
-
invoked; whether or not the stack is unwound before this invocation of
|
| 447 |
-
`std::terminate` is *implementation-defined* [[except.terminate]].
|
| 448 |
-
|
| 449 |
Referring to any non-static member or base class of an object in the
|
| 450 |
handler for a *function-try-block* of a constructor or destructor for
|
| 451 |
that object results in undefined behavior.
|
| 452 |
|
| 453 |
Exceptions thrown in destructors of objects with static storage duration
|
|
@@ -479,14 +516,14 @@ follows:
|
|
| 479 |
|
| 480 |
The lifetime of the variable ends when the handler exits, after the
|
| 481 |
destruction of any objects with automatic storage duration initialized
|
| 482 |
within the handler.
|
| 483 |
|
| 484 |
-
When the handler declares an object, any changes to that
|
| 485 |
-
affect the exception object. When the handler declares a
|
| 486 |
-
object, any changes to the referenced object are changes
|
| 487 |
-
|
| 488 |
|
| 489 |
## Exception specifications <a id="except.spec">[[except.spec]]</a>
|
| 490 |
|
| 491 |
The predicate indicating whether a function cannot exit via an exception
|
| 492 |
is called the *exception specification* of the function. If the
|
|
@@ -559,46 +596,19 @@ The declaration of `D::f` is ill-formed because it has a
|
|
| 559 |
potentially-throwing exception specification, whereas `B::f` has a
|
| 560 |
non-throwing exception specification.
|
| 561 |
|
| 562 |
— *end example*]
|
| 563 |
|
| 564 |
-
Whenever an exception is thrown and the search for a handler
|
| 565 |
-
[[except.handle]] encounters the outermost block of a function with a
|
| 566 |
-
non-throwing exception specification, the function `std::terminate` is
|
| 567 |
-
invoked [[except.terminate]].
|
| 568 |
-
|
| 569 |
-
[*Note 1*: An implementation is not permitted to reject an expression
|
| 570 |
-
merely because, when executed, it throws or might throw an exception
|
| 571 |
-
from a function with a non-throwing exception
|
| 572 |
-
specification. — *end note*]
|
| 573 |
-
|
| 574 |
-
[*Example 3*:
|
| 575 |
-
|
| 576 |
-
``` cpp
|
| 577 |
-
extern void f(); // potentially-throwing
|
| 578 |
-
|
| 579 |
-
void g() noexcept {
|
| 580 |
-
f(); // valid, even if f throws
|
| 581 |
-
throw 42; // valid, effectively a call to std::terminate
|
| 582 |
-
}
|
| 583 |
-
```
|
| 584 |
-
|
| 585 |
-
The call to `f` is well-formed despite the possibility for it to throw
|
| 586 |
-
an exception.
|
| 587 |
-
|
| 588 |
-
— *end example*]
|
| 589 |
-
|
| 590 |
An expression E is *potentially-throwing* if
|
| 591 |
|
| 592 |
- E is a function call [[expr.call]] whose *postfix-expression* has a
|
| 593 |
function type, or a pointer-to-function type, with a
|
| 594 |
potentially-throwing exception specification, or
|
| 595 |
- E implicitly invokes a function (such as an overloaded operator, an
|
| 596 |
allocation function in a *new-expression*, a constructor for a
|
| 597 |
-
function argument, or a destructor
|
| 598 |
-
|
| 599 |
-
specification, or
|
| 600 |
- E is a *throw-expression* [[expr.throw]], or
|
| 601 |
- E is a `dynamic_cast` expression that casts to a reference type and
|
| 602 |
requires a runtime check [[expr.dynamic.cast]], or
|
| 603 |
- E is a `typeid` expression applied to a (possibly parenthesized)
|
| 604 |
built-in unary `*` operator applied to a pointer to a polymorphic
|
|
@@ -616,11 +626,11 @@ only if any of the following constructs is potentially-throwing:
|
|
| 616 |
potentially constructed subobject, or
|
| 617 |
- a subexpression of such an initialization, such as a default argument
|
| 618 |
expression, or,
|
| 619 |
- for a default constructor, a default member initializer.
|
| 620 |
|
| 621 |
-
[*Note
|
| 622 |
invoked when an exception is thrown during the execution of a
|
| 623 |
constructor [[except.ctor]], their exception specifications do not
|
| 624 |
contribute to the exception specification of the constructor, because an
|
| 625 |
exception thrown from such a destructor would call the function
|
| 626 |
`std::terminate` rather than escape the constructor
|
|
@@ -646,11 +656,11 @@ specification.
|
|
| 646 |
The exception specification for a comparison operator function
|
| 647 |
[[over.binary]] without a *noexcept-specifier* that is defaulted on its
|
| 648 |
first declaration is potentially-throwing if and only if any expression
|
| 649 |
in the implicit definition is potentially-throwing.
|
| 650 |
|
| 651 |
-
[*Example
|
| 652 |
|
| 653 |
``` cpp
|
| 654 |
struct A {
|
| 655 |
A(int = (A(5), 0)) noexcept;
|
| 656 |
A(const A&) noexcept;
|
|
@@ -682,43 +692,45 @@ base class function has a non-throwing exception specification.
|
|
| 682 |
|
| 683 |
An exception specification is considered to be *needed* when:
|
| 684 |
|
| 685 |
- in an expression, the function is selected by overload resolution
|
| 686 |
[[over.match]], [[over.over]];
|
| 687 |
-
- the function is odr-used [[term.odr.use]]
|
| 688 |
-
unevaluated operand, would be odr-used if the expression were
|
| 689 |
-
potentially-evaluated;
|
| 690 |
- the exception specification is compared to that of another declaration
|
| 691 |
(e.g., an explicit specialization or an overriding virtual function);
|
| 692 |
- the function is defined; or
|
| 693 |
- the exception specification is needed for a defaulted function that
|
| 694 |
-
calls the function. \[*Note
|
| 695 |
require the exception specification of a base member function to be
|
| 696 |
evaluated until the implicit exception specification of the derived
|
| 697 |
function is needed, but an explicit *noexcept-specifier* needs the
|
| 698 |
implicit exception specification to compare against. — *end note*]
|
| 699 |
|
| 700 |
The exception specification of a defaulted function is evaluated as
|
| 701 |
described above only when needed; similarly, the *noexcept-specifier* of
|
| 702 |
-
a specialization of a
|
| 703 |
-
|
| 704 |
|
| 705 |
## Special functions <a id="except.special">[[except.special]]</a>
|
| 706 |
|
| 707 |
### General <a id="except.special.general">[[except.special.general]]</a>
|
| 708 |
|
| 709 |
The function `std::terminate` [[except.terminate]] is used by the
|
| 710 |
exception handling mechanism for coping with errors related to the
|
| 711 |
exception handling mechanism itself. The function
|
| 712 |
-
`std::
|
|
|
|
|
|
|
| 713 |
`std::nested_exception` [[except.nested]] can be used by a program to
|
| 714 |
capture the currently handled exception.
|
| 715 |
|
| 716 |
### The `std::terminate` function <a id="except.terminate">[[except.terminate]]</a>
|
| 717 |
|
| 718 |
-
|
| 719 |
-
|
|
|
|
|
|
|
| 720 |
|
| 721 |
[*Note 1*:
|
| 722 |
|
| 723 |
These situations are:
|
| 724 |
|
|
@@ -726,13 +738,16 @@ These situations are:
|
|
| 726 |
initialization of the exception object but before activation of a
|
| 727 |
handler for the exception [[except.throw]], calls a function that
|
| 728 |
exits via an exception, or
|
| 729 |
- when the exception handling mechanism cannot find a handler for a
|
| 730 |
thrown exception [[except.handle]], or
|
| 731 |
-
- when the search for a handler [[except.handle]]
|
| 732 |
-
|
| 733 |
-
|
|
|
|
|
|
|
|
|
|
| 734 |
- when the destruction of an object during stack unwinding
|
| 735 |
[[except.ctor]] terminates by throwing an exception, or
|
| 736 |
- when initialization of a non-block variable with static or thread
|
| 737 |
storage duration [[basic.start.dynamic]] exits via an exception, or
|
| 738 |
- when destruction of an object with static or thread storage duration
|
|
@@ -755,55 +770,64 @@ These situations are:
|
|
| 755 |
object of type `std::thread` that refers to a joinable thread
|
| 756 |
[[thread.thread.destr]], [[thread.thread.assign]], or
|
| 757 |
- when a call to a `wait()`, `wait_until()`, or `wait_for()` function on
|
| 758 |
a condition variable
|
| 759 |
[[thread.condition.condvar]], [[thread.condition.condvarany]] fails to
|
| 760 |
-
meet a postcondition
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 761 |
|
| 762 |
— *end note*]
|
| 763 |
|
| 764 |
-
In
|
| 765 |
-
|
| 766 |
-
|
| 767 |
-
|
| 768 |
-
|
| 769 |
-
|
| 770 |
-
it is *implementation-defined* whether the stack is unwound, unwound
|
| 771 |
partially, or not unwound at all before the function `std::terminate` is
|
| 772 |
invoked. In all other situations, the stack shall not be unwound before
|
| 773 |
the function `std::terminate` is invoked. An implementation is not
|
| 774 |
permitted to finish stack unwinding prematurely based on a determination
|
| 775 |
that the unwind process will eventually cause an invocation of the
|
| 776 |
function `std::terminate`.
|
| 777 |
|
| 778 |
-
### The `std::uncaught_exceptions` function <a id="except.uncaught">[[except.uncaught]]</a>
|
| 779 |
-
|
| 780 |
-
An exception is considered uncaught after completing the initialization
|
| 781 |
-
of the exception object [[except.throw]] until completing the activation
|
| 782 |
-
of a handler for the exception [[except.handle]].
|
| 783 |
-
|
| 784 |
-
[*Note 1*: As a consequence, an exception is considered uncaught during
|
| 785 |
-
any stack unwinding resulting from it being thrown. — *end note*]
|
| 786 |
-
|
| 787 |
-
If an exception is rethrown [[expr.throw]], [[propagation]], it is
|
| 788 |
-
considered uncaught from the point of rethrow until the rethrown
|
| 789 |
-
exception is caught. The function `std::uncaught_exceptions`
|
| 790 |
-
[[uncaught.exceptions]] returns the number of uncaught exceptions in the
|
| 791 |
-
current thread.
|
| 792 |
-
|
| 793 |
<!-- Link reference definitions -->
|
| 794 |
[algorithms.parallel.defns]: algorithms.md#algorithms.parallel.defns
|
| 795 |
[algorithms.parallel.exceptions]: algorithms.md#algorithms.parallel.exceptions
|
|
|
|
|
|
|
|
|
|
| 796 |
[basic.start.dynamic]: basic.md#basic.start.dynamic
|
| 797 |
[basic.start.main]: basic.md#basic.start.main
|
| 798 |
[basic.start.term]: basic.md#basic.start.term
|
| 799 |
[basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
|
| 800 |
[basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
|
|
|
|
| 801 |
[class.abstract]: class.md#class.abstract
|
| 802 |
[class.base.init]: class.md#class.base.init
|
| 803 |
[class.copy.ctor]: class.md#class.copy.ctor
|
| 804 |
-
[class.copy.elision]: class.md#class.copy.elision
|
| 805 |
[class.dtor]: class.md#class.dtor
|
| 806 |
[class.inhctor.init]: class.md#class.inhctor.init
|
| 807 |
[conv.fctptr]: expr.md#conv.fctptr
|
| 808 |
[conv.ptr]: expr.md#conv.ptr
|
| 809 |
[conv.qual]: expr.md#conv.qual
|
|
@@ -819,15 +843,19 @@ current thread.
|
|
| 819 |
[except.spec]: #except.spec
|
| 820 |
[except.special]: #except.special
|
| 821 |
[except.special.general]: #except.special.general
|
| 822 |
[except.terminate]: #except.terminate
|
| 823 |
[except.throw]: #except.throw
|
| 824 |
-
[except.uncaught]: #except.uncaught
|
| 825 |
[exception.terminate]: support.md#exception.terminate
|
| 826 |
-
[
|
| 827 |
-
[
|
| 828 |
-
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 829 |
[expr.call]: expr.md#expr.call
|
| 830 |
[expr.const]: expr.md#expr.const
|
| 831 |
[expr.dynamic.cast]: expr.md#expr.dynamic.cast
|
| 832 |
[expr.new]: expr.md#expr.new
|
| 833 |
[expr.prim.lambda.capture]: expr.md#expr.prim.lambda.capture
|
|
@@ -842,10 +870,14 @@ current thread.
|
|
| 842 |
[propagation]: support.md#propagation
|
| 843 |
[stmt.jump]: stmt.md#stmt.jump
|
| 844 |
[stmt.label]: stmt.md#stmt.label
|
| 845 |
[stmt.pre]: stmt.md#stmt.pre
|
| 846 |
[stmt.return]: stmt.md#stmt.return
|
|
|
|
|
|
|
|
|
|
|
|
|
| 847 |
[structure.specifications]: library.md#structure.specifications
|
| 848 |
[support.start.term]: support.md#support.start.term
|
| 849 |
[temp.explicit]: temp.md#temp.explicit
|
| 850 |
[term.odr.use]: basic.md#term.odr.use
|
| 851 |
[thread.condition.condvar]: thread.md#thread.condition.condvar
|
|
|
|
| 183 |
handler with a matching type [[except.handle]]; “nearest” means the
|
| 184 |
handler for which the *compound-statement* or *ctor-initializer*
|
| 185 |
following the `try` keyword was most recently entered by the thread of
|
| 186 |
control and not yet exited.
|
| 187 |
|
| 188 |
+
Throwing an exception initializes an object with dynamic storage
|
| 189 |
+
duration, called the *exception object*. If the type of the exception
|
| 190 |
+
object would be an incomplete type [[basic.types.general]], an abstract
|
| 191 |
+
class type [[class.abstract]], or a pointer to an incomplete type other
|
| 192 |
+
than cv `void` [[basic.compound]], the program is ill-formed.
|
| 193 |
|
| 194 |
The memory for the exception object is allocated in an unspecified way,
|
| 195 |
except as noted in [[basic.stc.dynamic.allocation]]. If a handler exits
|
| 196 |
by rethrowing, control is passed to another handler for the same
|
| 197 |
exception object. The points of potential destruction for the exception
|
|
|
|
| 216 |
|
| 217 |
[*Note 3*: A thrown exception does not propagate to other threads
|
| 218 |
unless caught, stored, and rethrown using appropriate library functions;
|
| 219 |
see [[propagation]] and [[futures]]. — *end note*]
|
| 220 |
|
| 221 |
+
Let `T` denote the type of the exception object. Copy-initialization of
|
| 222 |
+
an object of type `T` from an lvalue of type `const T` in a context
|
| 223 |
+
unrelated to `T` shall be well-formed. If `T` is a class type, the
|
| 224 |
+
selected constructor is odr-used [[basic.def.odr]] and the destructor of
|
| 225 |
+
`T` is potentially invoked [[class.dtor]].
|
| 226 |
+
|
| 227 |
+
An exception is considered *uncaught* after completing the
|
| 228 |
+
initialization of the exception object until completing the activation
|
| 229 |
+
of a handler for the exception [[except.handle]].
|
| 230 |
+
|
| 231 |
+
[*Note 4*: As a consequence, an exception is considered uncaught during
|
| 232 |
+
any stack unwinding resulting from it being thrown. — *end note*]
|
| 233 |
+
|
| 234 |
+
If an exception is rethrown [[expr.throw]], [[propagation]], it is
|
| 235 |
+
considered uncaught from the point of rethrow until the rethrown
|
| 236 |
+
exception is caught.
|
| 237 |
+
|
| 238 |
+
[*Note 5*: The function `std::uncaught_exceptions`
|
| 239 |
+
[[uncaught.exceptions]] returns the number of uncaught exceptions in the
|
| 240 |
+
current thread. — *end note*]
|
| 241 |
|
| 242 |
An exception is considered caught when a handler for that exception
|
| 243 |
becomes active [[except.handle]].
|
| 244 |
|
| 245 |
+
[*Note 6*: An exception can have active handlers and still be
|
| 246 |
considered uncaught if it is rethrown. — *end note*]
|
| 247 |
|
| 248 |
If the exception handling mechanism handling an uncaught exception
|
| 249 |
+
directly invokes a function that exits via an exception, the function
|
| 250 |
+
`std::terminate` is invoked [[except.terminate]].
|
|
|
|
| 251 |
|
| 252 |
[*Example 2*:
|
| 253 |
|
| 254 |
``` cpp
|
| 255 |
struct C {
|
|
|
|
| 269 |
}
|
| 270 |
```
|
| 271 |
|
| 272 |
— *end example*]
|
| 273 |
|
| 274 |
+
[*Note 7*: If a destructor directly invoked by stack unwinding exits
|
| 275 |
via an exception, `std::terminate` is invoked. — *end note*]
|
| 276 |
|
| 277 |
+
## Stack unwinding <a id="except.ctor">[[except.ctor]]</a>
|
| 278 |
|
| 279 |
As control passes from the point where an exception is thrown to a
|
| 280 |
handler, objects are destroyed by a process, specified in this
|
| 281 |
subclause, called *stack unwinding*.
|
| 282 |
|
|
|
|
| 322 |
[*Note 1*: If such an object has a reference member that extends the
|
| 323 |
lifetime of a temporary object, this ends the lifetime of the reference
|
| 324 |
member, so the lifetime of the temporary object is effectively not
|
| 325 |
extended. — *end note*]
|
| 326 |
|
| 327 |
+
A subobject is *known to be initialized* if it is not an anonymous union
|
| 328 |
+
member and its initialization is specified
|
| 329 |
|
| 330 |
- in [[class.base.init]] for initialization by constructor,
|
| 331 |
- in [[class.copy.ctor]] for initialization by defaulted copy/move
|
| 332 |
constructor,
|
| 333 |
- in [[class.inhctor.init]] for initialization by inherited constructor,
|
|
|
|
| 431 |
[*Note 2*: This makes it possible to write handlers that can never be
|
| 432 |
executed, for example by placing a handler for a final derived class
|
| 433 |
after a handler for a corresponding unambiguous public base
|
| 434 |
class. — *end note*]
|
| 435 |
|
| 436 |
+
A `...` in a handler’s *exception-declaration* specifies a match for any
|
|
|
|
| 437 |
exception. If present, a `...` handler shall be the last handler for its
|
| 438 |
try block.
|
| 439 |
|
| 440 |
If no match is found among the handlers for a try block, the search for
|
| 441 |
a matching handler continues in a dynamically surrounding try block of
|
| 442 |
the same thread.
|
| 443 |
|
| 444 |
+
If the search for a handler exits the function body of a function with a
|
| 445 |
+
non-throwing exception specification, the function `std::terminate`
|
| 446 |
+
[[except.terminate]] is invoked.
|
| 447 |
+
|
| 448 |
+
[*Note 3*: An implementation is not permitted to reject an expression
|
| 449 |
+
merely because, when executed, it throws or might throw an exception
|
| 450 |
+
from a function with a non-throwing exception
|
| 451 |
+
specification. — *end note*]
|
| 452 |
+
|
| 453 |
+
[*Example 2*:
|
| 454 |
+
|
| 455 |
+
``` cpp
|
| 456 |
+
extern void f(); // potentially-throwing
|
| 457 |
+
|
| 458 |
+
void g() noexcept {
|
| 459 |
+
f(); // valid, even if f throws
|
| 460 |
+
throw 42; // valid, effectively a call to std::terminate
|
| 461 |
+
}
|
| 462 |
+
```
|
| 463 |
+
|
| 464 |
+
The call to `f` is well-formed despite the possibility for it to throw
|
| 465 |
+
an exception.
|
| 466 |
+
|
| 467 |
+
— *end example*]
|
| 468 |
+
|
| 469 |
+
If no matching handler is found, the function `std::terminate` is
|
| 470 |
+
invoked; whether or not the stack is unwound before this invocation of
|
| 471 |
+
`std::terminate` is *implementation-defined* [[except.terminate]].
|
| 472 |
+
|
| 473 |
A handler is considered *active* when initialization is complete for the
|
| 474 |
parameter (if any) of the catch clause.
|
| 475 |
|
| 476 |
+
[*Note 4*: The stack will have been unwound at that
|
| 477 |
point. — *end note*]
|
| 478 |
|
| 479 |
Also, an implicit handler is considered active when the function
|
| 480 |
`std::terminate` is entered due to a throw. A handler is no longer
|
| 481 |
considered active when the catch clause exits.
|
| 482 |
|
| 483 |
The exception with the most recently activated handler that is still
|
| 484 |
active is called the *currently handled exception*.
|
| 485 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 486 |
Referring to any non-static member or base class of an object in the
|
| 487 |
handler for a *function-try-block* of a constructor or destructor for
|
| 488 |
that object results in undefined behavior.
|
| 489 |
|
| 490 |
Exceptions thrown in destructors of objects with static storage duration
|
|
|
|
| 516 |
|
| 517 |
The lifetime of the variable ends when the handler exits, after the
|
| 518 |
destruction of any objects with automatic storage duration initialized
|
| 519 |
within the handler.
|
| 520 |
|
| 521 |
+
[*Note 5*: When the handler declares an object, any changes to that
|
| 522 |
+
object will not affect the exception object. When the handler declares a
|
| 523 |
+
reference to an object, any changes to the referenced object are changes
|
| 524 |
+
to the exception object. — *end note*]
|
| 525 |
|
| 526 |
## Exception specifications <a id="except.spec">[[except.spec]]</a>
|
| 527 |
|
| 528 |
The predicate indicating whether a function cannot exit via an exception
|
| 529 |
is called the *exception specification* of the function. If the
|
|
|
|
| 596 |
potentially-throwing exception specification, whereas `B::f` has a
|
| 597 |
non-throwing exception specification.
|
| 598 |
|
| 599 |
— *end example*]
|
| 600 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
An expression E is *potentially-throwing* if
|
| 602 |
|
| 603 |
- E is a function call [[expr.call]] whose *postfix-expression* has a
|
| 604 |
function type, or a pointer-to-function type, with a
|
| 605 |
potentially-throwing exception specification, or
|
| 606 |
- E implicitly invokes a function (such as an overloaded operator, an
|
| 607 |
allocation function in a *new-expression*, a constructor for a
|
| 608 |
+
function argument, or a destructor) that has a potentially-throwing
|
| 609 |
+
exception specification, or
|
|
|
|
| 610 |
- E is a *throw-expression* [[expr.throw]], or
|
| 611 |
- E is a `dynamic_cast` expression that casts to a reference type and
|
| 612 |
requires a runtime check [[expr.dynamic.cast]], or
|
| 613 |
- E is a `typeid` expression applied to a (possibly parenthesized)
|
| 614 |
built-in unary `*` operator applied to a pointer to a polymorphic
|
|
|
|
| 626 |
potentially constructed subobject, or
|
| 627 |
- a subexpression of such an initialization, such as a default argument
|
| 628 |
expression, or,
|
| 629 |
- for a default constructor, a default member initializer.
|
| 630 |
|
| 631 |
+
[*Note 1*: Even though destructors for fully-constructed subobjects are
|
| 632 |
invoked when an exception is thrown during the execution of a
|
| 633 |
constructor [[except.ctor]], their exception specifications do not
|
| 634 |
contribute to the exception specification of the constructor, because an
|
| 635 |
exception thrown from such a destructor would call the function
|
| 636 |
`std::terminate` rather than escape the constructor
|
|
|
|
| 656 |
The exception specification for a comparison operator function
|
| 657 |
[[over.binary]] without a *noexcept-specifier* that is defaulted on its
|
| 658 |
first declaration is potentially-throwing if and only if any expression
|
| 659 |
in the implicit definition is potentially-throwing.
|
| 660 |
|
| 661 |
+
[*Example 3*:
|
| 662 |
|
| 663 |
``` cpp
|
| 664 |
struct A {
|
| 665 |
A(int = (A(5), 0)) noexcept;
|
| 666 |
A(const A&) noexcept;
|
|
|
|
| 692 |
|
| 693 |
An exception specification is considered to be *needed* when:
|
| 694 |
|
| 695 |
- in an expression, the function is selected by overload resolution
|
| 696 |
[[over.match]], [[over.over]];
|
| 697 |
+
- the function is odr-used [[term.odr.use]];
|
|
|
|
|
|
|
| 698 |
- the exception specification is compared to that of another declaration
|
| 699 |
(e.g., an explicit specialization or an overriding virtual function);
|
| 700 |
- the function is defined; or
|
| 701 |
- the exception specification is needed for a defaulted function that
|
| 702 |
+
calls the function. \[*Note 2*: A defaulted declaration does not
|
| 703 |
require the exception specification of a base member function to be
|
| 704 |
evaluated until the implicit exception specification of the derived
|
| 705 |
function is needed, but an explicit *noexcept-specifier* needs the
|
| 706 |
implicit exception specification to compare against. — *end note*]
|
| 707 |
|
| 708 |
The exception specification of a defaulted function is evaluated as
|
| 709 |
described above only when needed; similarly, the *noexcept-specifier* of
|
| 710 |
+
a specialization of a templated function is instantiated only when
|
| 711 |
+
needed.
|
| 712 |
|
| 713 |
## Special functions <a id="except.special">[[except.special]]</a>
|
| 714 |
|
| 715 |
### General <a id="except.special.general">[[except.special.general]]</a>
|
| 716 |
|
| 717 |
The function `std::terminate` [[except.terminate]] is used by the
|
| 718 |
exception handling mechanism for coping with errors related to the
|
| 719 |
exception handling mechanism itself. The function
|
| 720 |
+
`std::uncaught_exceptions` [[uncaught.exceptions]] reports how many
|
| 721 |
+
exceptions are uncaught in the current thread. The function
|
| 722 |
+
`std::current_exception` [[propagation]] and the class
|
| 723 |
`std::nested_exception` [[except.nested]] can be used by a program to
|
| 724 |
capture the currently handled exception.
|
| 725 |
|
| 726 |
### The `std::terminate` function <a id="except.terminate">[[except.terminate]]</a>
|
| 727 |
|
| 728 |
+
Some errors in a program cannot be recovered from, such as when an
|
| 729 |
+
exception is not handled or a `std::thread` object is destroyed while
|
| 730 |
+
its thread function is still executing. In such cases, the function
|
| 731 |
+
`std::terminate` [[exception.terminate]] is invoked.
|
| 732 |
|
| 733 |
[*Note 1*:
|
| 734 |
|
| 735 |
These situations are:
|
| 736 |
|
|
|
|
| 738 |
initialization of the exception object but before activation of a
|
| 739 |
handler for the exception [[except.throw]], calls a function that
|
| 740 |
exits via an exception, or
|
| 741 |
- when the exception handling mechanism cannot find a handler for a
|
| 742 |
thrown exception [[except.handle]], or
|
| 743 |
+
- when the search for a handler [[except.handle]] exits the function
|
| 744 |
+
body of a function with a non-throwing exception specification
|
| 745 |
+
[[except.spec]], including when a contract-violation handler invoked
|
| 746 |
+
from an evaluation of a function contract assertion
|
| 747 |
+
[[basic.contract.eval]] associated with the function exits via an
|
| 748 |
+
exception, or
|
| 749 |
- when the destruction of an object during stack unwinding
|
| 750 |
[[except.ctor]] terminates by throwing an exception, or
|
| 751 |
- when initialization of a non-block variable with static or thread
|
| 752 |
storage duration [[basic.start.dynamic]] exits via an exception, or
|
| 753 |
- when destruction of an object with static or thread storage duration
|
|
|
|
| 770 |
object of type `std::thread` that refers to a joinable thread
|
| 771 |
[[thread.thread.destr]], [[thread.thread.assign]], or
|
| 772 |
- when a call to a `wait()`, `wait_until()`, or `wait_for()` function on
|
| 773 |
a condition variable
|
| 774 |
[[thread.condition.condvar]], [[thread.condition.condvarany]] fails to
|
| 775 |
+
meet a postcondition, or
|
| 776 |
+
- when a callback invocation exits via an exception when requesting stop
|
| 777 |
+
on a `std::stop_source` or a `std::inplace_stop_source`
|
| 778 |
+
[[stopsource.mem]], [[stopsource.inplace.mem]], or in the constructor
|
| 779 |
+
of `std::stop_callback` or `std::inplace_stop_callback`
|
| 780 |
+
[[stopcallback.cons]], [[stopcallback.inplace.cons]] when a callback
|
| 781 |
+
invocation exits via an exception, or
|
| 782 |
+
- when a `run_loop` object is destroyed that is still in the `running`
|
| 783 |
+
state [[exec.run.loop]], or
|
| 784 |
+
- when `unhandled_stopped` is called on a `with_awaitable_senders<T>`
|
| 785 |
+
object [[exec.with.awaitable.senders]] whose continuation is not a
|
| 786 |
+
handle to a coroutine whose promise type has an `unhandled_stopped`
|
| 787 |
+
member function, or
|
| 788 |
+
- when an object `scope` of type `std::execution::simple_counting_scope`
|
| 789 |
+
or `std::execution::counting_scope` is destroyed and `scope.state` is
|
| 790 |
+
not equal to *`joined`*, *`unused`*, or *`unused-and-closed`*
|
| 791 |
+
[[exec.simple.counting.ctor]], or
|
| 792 |
+
- when `std::execution::get_parallel_scheduler` is called and
|
| 793 |
+
`std::execution::system_context_replaceability::query_parallel_scheduler_backend()`
|
| 794 |
+
returns a null pointer value [[exec.par.scheduler]], or
|
| 795 |
+
- when an exception is thrown from a coroutine `std::execution::task`
|
| 796 |
+
[[exec.task]] which doesn’t support a
|
| 797 |
+
`std::execution::set_error_t(std::exception_ptr)` completion.
|
| 798 |
|
| 799 |
— *end note*]
|
| 800 |
|
| 801 |
+
In the situation where no matching handler is found, it is
|
| 802 |
+
*implementation-defined* whether or not the stack is unwound before
|
| 803 |
+
`std::terminate` is invoked. In the situation where the search for a
|
| 804 |
+
handler [[except.handle]] exits the function body of a function with a
|
| 805 |
+
non-throwing exception specification [[except.spec]], it is
|
| 806 |
+
*implementation-defined* whether the stack is unwound, unwound
|
|
|
|
| 807 |
partially, or not unwound at all before the function `std::terminate` is
|
| 808 |
invoked. In all other situations, the stack shall not be unwound before
|
| 809 |
the function `std::terminate` is invoked. An implementation is not
|
| 810 |
permitted to finish stack unwinding prematurely based on a determination
|
| 811 |
that the unwind process will eventually cause an invocation of the
|
| 812 |
function `std::terminate`.
|
| 813 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 814 |
<!-- Link reference definitions -->
|
| 815 |
[algorithms.parallel.defns]: algorithms.md#algorithms.parallel.defns
|
| 816 |
[algorithms.parallel.exceptions]: algorithms.md#algorithms.parallel.exceptions
|
| 817 |
+
[basic.compound]: basic.md#basic.compound
|
| 818 |
+
[basic.contract.eval]: basic.md#basic.contract.eval
|
| 819 |
+
[basic.def.odr]: basic.md#basic.def.odr
|
| 820 |
[basic.start.dynamic]: basic.md#basic.start.dynamic
|
| 821 |
[basic.start.main]: basic.md#basic.start.main
|
| 822 |
[basic.start.term]: basic.md#basic.start.term
|
| 823 |
[basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
|
| 824 |
[basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
|
| 825 |
+
[basic.types.general]: basic.md#basic.types.general
|
| 826 |
[class.abstract]: class.md#class.abstract
|
| 827 |
[class.base.init]: class.md#class.base.init
|
| 828 |
[class.copy.ctor]: class.md#class.copy.ctor
|
|
|
|
| 829 |
[class.dtor]: class.md#class.dtor
|
| 830 |
[class.inhctor.init]: class.md#class.inhctor.init
|
| 831 |
[conv.fctptr]: expr.md#conv.fctptr
|
| 832 |
[conv.ptr]: expr.md#conv.ptr
|
| 833 |
[conv.qual]: expr.md#conv.qual
|
|
|
|
| 843 |
[except.spec]: #except.spec
|
| 844 |
[except.special]: #except.special
|
| 845 |
[except.special.general]: #except.special.general
|
| 846 |
[except.terminate]: #except.terminate
|
| 847 |
[except.throw]: #except.throw
|
|
|
|
| 848 |
[exception.terminate]: support.md#exception.terminate
|
| 849 |
+
[exec.par.scheduler]: exec.md#exec.par.scheduler
|
| 850 |
+
[exec.run.loop]: exec.md#exec.run.loop
|
| 851 |
+
[exec.simple.counting.ctor]: exec.md#exec.simple.counting.ctor
|
| 852 |
+
[exec.task]: exec.md#exec.task
|
| 853 |
+
[exec.with.awaitable.senders]: exec.md#exec.with.awaitable.senders
|
| 854 |
+
[execpol.par]: algorithms.md#execpol.par
|
| 855 |
+
[execpol.parunseq]: algorithms.md#execpol.parunseq
|
| 856 |
+
[execpol.seq]: algorithms.md#execpol.seq
|
| 857 |
[expr.call]: expr.md#expr.call
|
| 858 |
[expr.const]: expr.md#expr.const
|
| 859 |
[expr.dynamic.cast]: expr.md#expr.dynamic.cast
|
| 860 |
[expr.new]: expr.md#expr.new
|
| 861 |
[expr.prim.lambda.capture]: expr.md#expr.prim.lambda.capture
|
|
|
|
| 870 |
[propagation]: support.md#propagation
|
| 871 |
[stmt.jump]: stmt.md#stmt.jump
|
| 872 |
[stmt.label]: stmt.md#stmt.label
|
| 873 |
[stmt.pre]: stmt.md#stmt.pre
|
| 874 |
[stmt.return]: stmt.md#stmt.return
|
| 875 |
+
[stopcallback.cons]: thread.md#stopcallback.cons
|
| 876 |
+
[stopcallback.inplace.cons]: thread.md#stopcallback.inplace.cons
|
| 877 |
+
[stopsource.inplace.mem]: thread.md#stopsource.inplace.mem
|
| 878 |
+
[stopsource.mem]: thread.md#stopsource.mem
|
| 879 |
[structure.specifications]: library.md#structure.specifications
|
| 880 |
[support.start.term]: support.md#support.start.term
|
| 881 |
[temp.explicit]: temp.md#temp.explicit
|
| 882 |
[term.odr.use]: basic.md#term.odr.use
|
| 883 |
[thread.condition.condvar]: thread.md#thread.condition.condvar
|