From Jason Turner

[except]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpklh98kwr/{from.md → to.md} +212 -188
tmp/tmpklh98kwr/{from.md → to.md} RENAMED
@@ -1,7 +1,9 @@
1
  # Exception handling <a id="except">[[except]]</a>
2
 
 
 
3
  Exception handling provides a way of transferring control and
4
  information from a point in the execution of a thread to an exception
5
  handler associated with a point previously passed by the execution. A
6
  handler will be invoked only by throwing an exception in code executed
7
  in the handler’s try block or in functions called from the handler’s try
@@ -22,24 +24,24 @@ handler-seq:
22
  handler handler-seqₒₚₜ
23
  ```
24
 
25
  ``` bnf
26
  handler:
27
- 'catch (' exception-declaration ')' compound-statement
28
  ```
29
 
30
  ``` bnf
31
  exception-declaration:
32
  attribute-specifier-seqₒₚₜ type-specifier-seq declarator
33
  attribute-specifier-seqₒₚₜ type-specifier-seq abstract-declaratorₒₚₜ
34
  '...'
35
  ```
36
 
37
  The optional *attribute-specifier-seq* in an *exception-declaration*
38
- appertains to the parameter of the catch clause ([[except.handle]]).
39
 
40
- A *try-block* is a *statement* (Clause  [[stmt.stmt]]).
41
 
42
  [*Note 1*: Within this Clause “try block” is taken to mean both
43
  *try-block* and *function-try-block*. — *end note*]
44
 
45
  A `goto` or `switch` statement shall not be used to transfer control
@@ -47,19 +49,19 @@ into a try block or into a handler.
47
 
48
  [*Example 1*:
49
 
50
  ``` cpp
51
  void f() {
52
- goto l1; // ill-formed
53
- goto l2; // ill-formed
54
  try {
55
  goto l1; // OK
56
- goto l2; // ill-formed
57
  l1: ;
58
  } catch (...) {
59
  l2: ;
60
- goto l1; // ill-formed
61
  goto l2; // OK
62
  }
63
  }
64
  ```
65
 
@@ -118,23 +120,22 @@ try : i(f(ii)), d(id) {
118
  }
119
  ```
120
 
121
  — *end example*]
122
 
123
- In this section, “before” and “after” refer to the “sequenced before”
124
- relation ([[intro.execution]]).
125
 
126
  ## Throwing an exception <a id="except.throw">[[except.throw]]</a>
127
 
128
  Throwing an exception transfers control to a handler.
129
 
130
  [*Note 1*: An exception can be thrown from one of the following
131
- contexts: *throw-expression*s ([[expr.throw]]), allocation functions (
132
- [[basic.stc.dynamic.allocation]]), `dynamic_cast` (
133
- [[expr.dynamic.cast]]), `typeid` ([[expr.typeid]]), *new-expression*s (
134
- [[expr.new]]), and standard library functions (
135
- [[structure.specifications]]). — *end note*]
136
 
137
  An object is passed and the type of that object determines which
138
  handlers can catch it.
139
 
140
  [*Example 1*:
@@ -177,39 +178,39 @@ try {
177
  ```
178
 
179
  — *end example*]
180
 
181
  When an exception is thrown, control is transferred to the nearest
182
- handler with a matching type ([[except.handle]]); “nearest” means the
183
  handler for which the *compound-statement* or *ctor-initializer*
184
  following the `try` keyword was most recently entered by the thread of
185
  control and not yet exited.
186
 
187
- Throwing an exception copy-initializes ([[dcl.init]], [[class.copy]]) a
188
- temporary object, called the *exception object*. An lvalue denoting the
189
- temporary is used to initialize the variable declared in the matching
190
- *handler* ([[except.handle]]). If the type of the exception object
191
- would be an incomplete type or a pointer to an incomplete type other
192
- than 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
198
  object are:
199
 
200
  - when an active handler for the exception exits by any means other than
201
  rethrowing, immediately after the destruction of the object (if any)
202
  declared in the *exception-declaration* in the handler;
203
- - when an object of type `std::exception_ptr` ([[propagation]]) that
204
  refers to the exception object is destroyed, before the destructor of
205
  `std::exception_ptr` returns.
206
 
207
  Among all points of potential destruction for the exception object,
208
  there is an unspecified last one where the exception object is
209
- destroyed. All other points happen before that last one (
210
- [[intro.races]]).
211
 
212
  [*Note 2*: No other thread synchronization is implied in exception
213
  handling. — *end note*]
214
 
215
  The implementation may then deallocate the memory for the exception
@@ -220,61 +221,65 @@ unless caught, stored, and rethrown using appropriate library functions;
220
  see  [[propagation]] and  [[futures]]. — *end note*]
221
 
222
  When the thrown object is a class object, the constructor selected for
223
  the copy-initialization as well as the constructor selected for a
224
  copy-initialization considering the thrown object as an lvalue shall be
225
- non-deleted and accessible, even if the copy/move operation is elided (
226
- [[class.copy]]). The destructor is potentially invoked (
227
- [[class.dtor]]).
228
 
229
  An exception is considered caught when a handler for that exception
230
- becomes active ([[except.handle]]).
231
 
232
  [*Note 4*: An exception can have active handlers and still be
233
  considered uncaught if it is rethrown. — *end note*]
234
 
235
- If the exception handling mechanism handling an uncaught exception (
236
- [[except.uncaught]]) directly invokes a function that exits via an
237
- exception, `std::terminate` is called ([[except.terminate]]).
238
 
239
  [*Example 2*:
240
 
241
  ``` cpp
242
  struct C {
243
  C() { }
244
  C(const C&) {
245
  if (std::uncaught_exceptions()) {
246
- throw 0; // throw during copy to handler's exception-declaration object~([except.handle])
247
  }
248
  }
249
  };
250
 
251
  int main() {
252
  try {
253
- throw C(); // calls std::terminate() if construction of the handler's
254
- // exception-declaration object is not elided~([class.copy])
255
  } catch(C) { }
256
  }
257
  ```
258
 
259
  — *end example*]
260
 
261
- [*Note 5*: Consequently, destructors should generally catch exceptions
262
- and not let them propagate. — *end note*]
 
 
 
 
263
 
264
  ## Constructors and destructors <a id="except.ctor">[[except.ctor]]</a>
265
 
266
  As control passes from the point where an exception is thrown to a
267
- handler, destructors are invoked by a process, specified in this
268
- section, called *stack unwinding*.
269
 
270
- The destructor is invoked for each automatic object of class type
271
  constructed, but not yet destroyed, since the try block was entered. If
272
  an exception is thrown during the destruction of temporaries or local
273
- variables for a `return` statement ([[stmt.return]]), the destructor
274
- for the returned object (if any) is also invoked. The objects are
275
- destroyed in the reverse order of the completion of their construction.
276
 
277
  [*Example 1*:
278
 
279
  ``` cpp
280
  struct A { };
@@ -292,37 +297,44 @@ A f() {
292
  return {}; // #2
293
  }
294
  ```
295
 
296
  At \#1, the returned object of type `A` is constructed. Then, the local
297
- variable `b` is destroyed ([[stmt.jump]]). Next, the local variable `y`
298
- is destroyed, causing stack unwinding, resulting in the destruction of
299
- the returned object, followed by the destruction of the local variable
300
- `a`. Finally, the returned object is constructed again at \#2.
301
 
302
  — *end example*]
303
 
304
  If the initialization or destruction of an object other than by
305
  delegating constructor is terminated by an exception, the destructor is
306
  invoked for each of the object’s direct subobjects and, for a complete
307
  object, virtual base class subobjects, whose initialization has
308
- completed ([[dcl.init]]) and whose destructor has not yet begun
309
- execution, except that in the case of destruction, the variant members
310
- of a union-like class are not destroyed. The subobjects are destroyed in
311
- the reverse order of the completion of their construction. Such
312
- destruction is sequenced before entering a handler of the
313
- *function-try-block* of the constructor or destructor, if any.
 
 
 
 
 
 
 
314
 
315
  If the *compound-statement* of the *function-body* of a delegating
316
  constructor for an object exits via an exception, the object’s
317
  destructor is invoked. Such destruction is sequenced before entering a
318
  handler of the *function-try-block* of a delegating constructor for that
319
  object, if any.
320
 
321
- [*Note 1*: If the object was allocated by a *new-expression* (
322
- [[expr.new]]), the matching deallocation function (
323
- [[basic.stc.dynamic.deallocation]]), if any, is called to free the
324
  storage occupied by the object. — *end note*]
325
 
326
  ## Handling an exception <a id="except.handle">[[except.handle]]</a>
327
 
328
  The *exception-declaration* in a *handler* describes the type(s) of
@@ -341,23 +353,23 @@ A *handler* is a match for an exception object of type `E` if
341
  - The *handler* is of type cv `T` or cv `T&` and `E` and `T` are the
342
  same type (ignoring the top-level *cv-qualifier*s), or
343
  - the *handler* is of type cv `T` or cv `T&` and `T` is an unambiguous
344
  public base class of `E`, or
345
  - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
346
- or pointer to member type and `E` is a pointer or pointer to member
347
  type that can be converted to `T` by one or more of
348
- - a standard pointer conversion ([[conv.ptr]]) not involving
349
- conversions to pointers to private or protected or ambiguous classes
350
- - a function pointer conversion ([[conv.fctptr]])
351
- - a qualification conversion ([[conv.qual]]), or
352
  - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
353
- or pointer to member type and `E` is `std::nullptr_t`.
354
 
355
  [*Note 1*: A *throw-expression* whose operand is an integer literal
356
- with value zero does not match a handler of pointer or pointer to member
357
  type. A handler of reference to array or function type is never a match
358
- for any exception object ([[expr.throw]]). — *end note*]
359
 
360
  [*Example 1*:
361
 
362
  ``` cpp
363
  class Matherr { ... virtual void vf(); };
@@ -397,44 +409,44 @@ try block.
397
 
398
  If no match is found among the handlers for a try block, the search for
399
  a matching handler continues in a dynamically surrounding try block of
400
  the same thread.
401
 
402
- A handler is considered active when initialization is complete for the
403
  parameter (if any) of the catch clause.
404
 
405
  [*Note 3*: The stack will have been unwound at that
406
  point. — *end note*]
407
 
408
- Also, an implicit handler is considered active when `std::terminate()`
409
- is entered due to a throw. A handler is no longer considered active when
410
- the catch clause exits.
411
 
412
  The exception with the most recently activated handler that is still
413
  active is called the *currently handled exception*.
414
 
415
- If no matching handler is found, the function `std::terminate()` is
416
  called; whether or not the stack is unwound before this call to
417
- `std::terminate()` is *implementation-defined* ([[except.terminate]]).
418
 
419
  Referring to any non-static member or base class of an object in the
420
  handler for a *function-try-block* of a constructor or destructor for
421
  that object results in undefined behavior.
422
 
423
  The scope and lifetime of the parameters of a function or constructor
424
  extend into the handlers of a *function-try-block*.
425
 
426
  Exceptions thrown in destructors of objects with static storage duration
427
  or in constructors of namespace-scope objects with static storage
428
- duration are not caught by a *function-try-block* on the `main`
429
- function ([[basic.start.main]]). Exceptions thrown in destructors of
430
- objects with thread storage duration or in constructors of
431
- namespace-scope objects with thread storage duration are not caught by a
432
- *function-try-block* on the initial function of the thread.
433
 
434
- If a return statement appears in a handler of the *function-try-block*
435
- of a constructor, the program is ill-formed.
436
 
437
  The currently handled exception is rethrown if control reaches the end
438
  of a handler of the *function-try-block* of a constructor or destructor.
439
  Otherwise, flowing off the end of the *compound-statement* of a
440
  *handler* of a *function-try-block* is equivalent to flowing off the end
@@ -442,18 +454,19 @@ of the *compound-statement* of that function (see [[stmt.return]]).
442
 
443
  The variable declared by the *exception-declaration*, of type cv `T` or
444
  cv `T&`, is initialized from the exception object, of type `E`, as
445
  follows:
446
 
447
- - if `T` is a base class of `E`, the variable is copy-initialized (
448
- [[dcl.init]]) from the corresponding base class subobject of the
449
  exception object;
450
- - otherwise, the variable is copy-initialized ([[dcl.init]]) from the
451
  exception object.
452
 
453
  The lifetime of the variable ends when the handler exits, after the
454
- destruction of any automatic objects initialized within the handler.
 
455
 
456
  When the handler declares an object, any changes to that object will not
457
  affect the exception object. When the handler declares a reference to an
458
  object, any changes to the referenced object are changes to the
459
  exception object and will have effect should that object be rethrown.
@@ -464,37 +477,34 @@ The predicate indicating whether a function cannot exit via an exception
464
  is called the *exception specification* of the function. If the
465
  predicate is false, the function has a *potentially-throwing exception
466
  specification*, otherwise it has a *non-throwing exception
467
  specification*. The exception specification is either defined
468
  implicitly, or defined explicitly by using a *noexcept-specifier* as a
469
- suffix of a function declarator ([[dcl.fct]]).
470
 
471
  ``` bnf
472
  noexcept-specifier:
473
  'noexcept' '(' constant-expression ')'
474
  'noexcept'
475
- 'throw' '(' ')'
476
  ```
477
 
478
  In a *noexcept-specifier*, the *constant-expression*, if supplied, shall
479
- be a contextually converted constant expression of type `bool` (
480
- [[expr.const]]); that constant expression is the exception specification
481
  of the function type in which the *noexcept-specifier* appears. A `(`
482
  token that follows `noexcept` is part of the *noexcept-specifier* and
483
- does not commence an initializer ([[dcl.init]]). The
484
- *noexcept-specifier* `noexcept` without a *constant-expression* is
485
- equivalent to the *noexcept-specifier* `noexcept(true)`. The
486
- *noexcept-specifier* `throw()` is deprecated ([[depr.except.spec]]),
487
- and equivalent to the *noexcept-specifier* `noexcept(true)`.
488
 
489
  If a declaration of a function does not have a *noexcept-specifier*, the
490
  declaration has a potentially throwing exception specification unless it
491
  is a destructor or a deallocation function or is defaulted on its first
492
- declaration, in which cases the exception specfication is as specified
493
  below and no other declaration for that function shall have a
494
- *noexcept-specifier*. In an explicit instantiation ([[temp.explicit]])
495
- a *noexcept-specifier* may be specified, but is not required. If a
496
  *noexcept-specifier* is specified in an explicit instantiation
497
  directive, the exception specification shall be the same as the
498
  exception specification of all other declarations of that function. A
499
  diagnostic is required only if the exception specifications are not the
500
  same within a single translation unit.
@@ -513,11 +523,11 @@ struct B {
513
  virtual void g();
514
  virtual void h() noexcept = delete;
515
  };
516
 
517
  struct D: B {
518
- void f(); // ill-formed
519
  void g() noexcept; // OK
520
  void h() = delete; // OK
521
  };
522
  ```
523
 
@@ -525,18 +535,19 @@ The declaration of `D::f` is ill-formed because it has a
525
  potentially-throwing exception specification, whereas `B::f` has a
526
  non-throwing exception specification.
527
 
528
  — *end example*]
529
 
530
- Whenever an exception is thrown and the search for a handler (
531
- [[except.handle]]) encounters the outermost block of a function with a
532
- non-throwing exception specification, the function `std::terminate()` is
533
- called ([[except.terminate]]).
534
 
535
- [*Note 1*: An implementation shall not reject an expression merely
536
- because, when executed, it throws or might throw an exception from a
537
- function with a non-throwing exception specification. — *end note*]
 
538
 
539
  [*Example 2*:
540
 
541
  ``` cpp
542
  extern void f(); // potentially-throwing
@@ -550,26 +561,26 @@ void g() noexcept {
550
  The call to `f` is well-formed even though, when called, `f` might throw
551
  an exception.
552
 
553
  — *end example*]
554
 
555
- An expression `e` is *potentially-throwing* if
556
 
557
- - `e` is a function call ([[expr.call]]) whose *postfix-expression* has
558
- a function type, or a pointer-to-function type, with a
559
  potentially-throwing exception specification, or
560
- - `e` implicitly invokes a function (such as an overloaded operator, an
561
  allocation function in a *new-expression*, a constructor for a
562
- function argument, or a destructor if `e` is a full-expression (
563
- [[intro.execution]])) that is potentially-throwing, or
564
- - `e` is a *throw-expression* ([[expr.throw]]), or
565
- - `e` is a `dynamic_cast` expression that casts to a reference type and
566
- requires a runtime check ([[expr.dynamic.cast]]), or
567
- - `e` is a `typeid` expression applied to a (possibly parenthesized)
568
  built-in unary `*` operator applied to a pointer to a polymorphic
569
- class type ([[expr.typeid]]), or
570
- - any of the immediate subexpressions ([[intro.execution]]) of `e` is
571
  potentially-throwing.
572
 
573
  An implicitly-declared constructor for a class `X`, or a constructor
574
  without a *noexcept-specifier* that is defaulted on its first
575
  declaration, has a potentially-throwing exception specification if and
@@ -582,44 +593,51 @@ only if any of the following constructs is potentially-throwing:
582
  expression, or,
583
  - for a default constructor, a default member initializer.
584
 
585
  [*Note 2*: Even though destructors for fully-constructed subobjects are
586
  invoked when an exception is thrown during the execution of a
587
- constructor ([[except.ctor]]), their exception specifications do not
588
  contribute to the exception specification of the constructor, because an
589
- exception thrown from such a destructor would call `std::terminate`
590
- rather than escape the constructor ([[except.throw]],
591
  [[except.terminate]]). — *end note*]
592
 
593
  The exception specification for an implicitly-declared destructor, or a
594
  destructor without a *noexcept-specifier*, is potentially-throwing if
595
  and only if any of the destructors for any of its potentially
596
- constructed subojects is potentially throwing.
 
 
597
 
598
  The exception specification for an implicitly-declared assignment
599
  operator, or an assignment-operator without a *noexcept-specifier* that
600
  is defaulted on its first declaration, is potentially-throwing if and
601
  only if the invocation of any assignment operator in the implicit
602
  definition is potentially-throwing.
603
 
604
- A deallocation function ([[basic.stc.dynamic.deallocation]]) with no
605
  explicit *noexcept-specifier* has a non-throwing exception
606
  specification.
607
 
 
 
 
 
 
608
  [*Example 3*:
609
 
610
  ``` cpp
611
  struct A {
612
  A(int = (A(5), 0)) noexcept;
613
  A(const A&) noexcept;
614
  A(A&&) noexcept;
615
  ~A();
616
  };
617
  struct B {
618
- B() throw();
619
  B(const B&) = default; // implicit exception specification is noexcept(true)
620
- B(B&&, int = (throw Y(), 0)) noexcept;
621
  ~B() noexcept(false);
622
  };
623
  int n = 7;
624
  struct D : public A, public B {
625
  int * p = new int[n];
@@ -640,109 +658,112 @@ base class function has a non-throwing exception specification.
640
  An exception specification is considered to be *needed* when:
641
 
642
  - in an expression, the function is the unique lookup result or the
643
  selected member of a set of overloaded functions ([[basic.lookup]],
644
  [[over.match]], [[over.over]]);
645
- - the function is odr-used ([[basic.def.odr]]) or, if it appears in an
646
  unevaluated operand, would be odr-used if the expression were
647
  potentially-evaluated;
648
  - the exception specification is compared to that of another declaration
649
  (e.g., an explicit specialization or an overriding virtual function);
650
  - the function is defined; or
651
- - the exception specification is needed for a defaulted special member
652
- function that calls the function. \[*Note 3*: A defaulted declaration
653
- does not require the exception specification of a base member function
654
- to be evaluated until the implicit exception specification of the
655
- derived function is needed, but an explicit *noexcept-specifier* needs
656
- the implicit exception specification to compare
657
- against. — *end note*]
658
 
659
- The exception specification of a defaulted special member function is
660
- evaluated as described above only when needed; similarly, the
661
- *noexcept-specifier* of a specialization of a function template or
662
- member function of a class template is instantiated only when needed.
663
 
664
  ## Special functions <a id="except.special">[[except.special]]</a>
665
 
666
- The function `std::terminate()` ([[except.terminate]]) is used by the
667
  exception handling mechanism for coping with errors related to the
668
  exception handling mechanism itself. The function
669
- `std::current_exception()` ([[propagation]]) and the class
670
- `std::nested_exception` ([[except.nested]]) can be used by a program to
671
  capture the currently handled exception.
672
 
673
- ### The `std::terminate()` function <a id="except.terminate">[[except.terminate]]</a>
674
 
675
  In some situations exception handling must be abandoned for less subtle
676
  error handling techniques.
677
 
678
  [*Note 1*:
679
 
680
  These situations are:
681
 
682
  - when the exception handling mechanism, after completing the
683
  initialization of the exception object but before activation of a
684
- handler for the exception ([[except.throw]]), calls a function that
685
  exits via an exception, or
686
  - when the exception handling mechanism cannot find a handler for a
687
- thrown exception ([[except.handle]]), or
688
- - when the search for a handler ([[except.handle]]) encounters the
689
  outermost block of a function with a non-throwing exception
690
- specification ([[except.spec]]), or
691
- - when the destruction of an object during stack unwinding (
692
- [[except.ctor]]) terminates by throwing an exception, or
693
  - when initialization of a non-local variable with static or thread
694
- storage duration ([[basic.start.dynamic]]) exits via an exception, or
695
  - when destruction of an object with static or thread storage duration
696
- exits via an exception ([[basic.start.term]]), or
697
  - when execution of a function registered with `std::atexit` or
698
- `std::at_quick_exit` exits via an exception ([[support.start.term]]),
699
- or
700
- - when a *throw-expression* ([[expr.throw]]) with no operand attempts
701
- to rethrow an exception and no exception is being handled (
702
- [[except.throw]]), or
703
  - when the function `std::nested_exception::rethrow_nested` is called
704
- for an object that has captured no exception ([[except.nested]]), or
705
  - when execution of the initial function of a thread exits via an
706
- exception ([[thread.thread.constr]]), or
707
  - for a parallel algorithm whose `ExecutionPolicy` specifies such
708
  behavior ([[execpol.seq]], [[execpol.par]], [[execpol.parunseq]]),
709
- when execution of an element access function (
710
- [[algorithms.parallel.defns]]) of the parallel algorithm exits via an
711
- exception ([[algorithms.parallel.exceptions]]), or
712
- - when the destructor or the copy assignment operator is invoked on an
713
  object of type `std::thread` that refers to a joinable thread (
714
- [[thread.thread.destr]],  [[thread.thread.assign]]), or
715
  - when a call to a `wait()`, `wait_until()`, or `wait_for()` function on
716
- a condition variable ([[thread.condition.condvar]], 
717
  [[thread.condition.condvarany]]) fails to meet a postcondition.
718
 
719
  — *end note*]
720
 
721
- In such cases, `std::terminate()` is called ([[exception.terminate]]).
722
- In the situation where no matching handler is found, it is
723
- *implementation-defined* whether or not the stack is unwound before
724
- `std::terminate()` is called. In the situation where the search for a
725
- handler ([[except.handle]]) encounters the outermost block of a
726
- function with a non-throwing exception specification ([[except.spec]]),
727
  it is *implementation-defined* whether the stack is unwound, unwound
728
- partially, or not unwound at all before `std::terminate()` is called. In
729
- all other situations, the stack shall not be unwound before
730
- `std::terminate()` is called. An implementation is not permitted to
731
- finish stack unwinding prematurely based on a determination that the
732
- unwind process will eventually cause a call to `std::terminate()`.
 
733
 
734
  ### The `std::uncaught_exceptions()` function <a id="except.uncaught">[[except.uncaught]]</a>
735
 
736
  An exception is considered uncaught after completing the initialization
737
- of the exception object ([[except.throw]]) until completing the
738
- activation of a handler for the exception ([[except.handle]]). This
739
- includes stack unwinding. If an exception is rethrown ([[expr.throw]],
740
- [[propagation]]), it is considered uncaught from the point of rethrow
741
- until the rethrown exception is caught. The function
742
- `std::uncaught_exceptions()` ([[uncaught.exceptions]]) returns the
743
- number of uncaught exceptions in the current thread.
 
 
 
 
744
 
745
  <!-- Link reference definitions -->
746
  [algorithms.parallel.defns]: algorithms.md#algorithms.parallel.defns
747
  [algorithms.parallel.exceptions]: algorithms.md#algorithms.parallel.exceptions
748
  [basic.def.odr]: basic.md#basic.def.odr
@@ -750,50 +771,53 @@ number of uncaught exceptions in the current thread.
750
  [basic.start.dynamic]: basic.md#basic.start.dynamic
751
  [basic.start.main]: basic.md#basic.start.main
752
  [basic.start.term]: basic.md#basic.start.term
753
  [basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
754
  [basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
755
- [class.copy]: special.md#class.copy
756
- [class.dtor]: special.md#class.dtor
757
- [conv.fctptr]: conv.md#conv.fctptr
758
- [conv.ptr]: conv.md#conv.ptr
759
- [conv.qual]: conv.md#conv.qual
 
 
760
  [dcl.fct]: dcl.md#dcl.fct
761
  [dcl.init]: dcl.md#dcl.init
762
- [depr.except.spec]: future.md#depr.except.spec
763
  [except]: #except
764
  [except.ctor]: #except.ctor
765
  [except.handle]: #except.handle
766
- [except.nested]: language.md#except.nested
 
767
  [except.spec]: #except.spec
768
  [except.special]: #except.special
769
  [except.terminate]: #except.terminate
770
  [except.throw]: #except.throw
771
  [except.uncaught]: #except.uncaught
772
- [exception.terminate]: language.md#exception.terminate
773
  [execpol.par]: utilities.md#execpol.par
774
  [execpol.parunseq]: utilities.md#execpol.parunseq
775
  [execpol.seq]: utilities.md#execpol.seq
776
  [expr.call]: expr.md#expr.call
777
  [expr.const]: expr.md#expr.const
778
  [expr.dynamic.cast]: expr.md#expr.dynamic.cast
779
  [expr.new]: expr.md#expr.new
780
  [expr.throw]: expr.md#expr.throw
781
  [expr.typeid]: expr.md#expr.typeid
782
  [futures]: thread.md#futures
783
- [intro.execution]: intro.md#intro.execution
784
- [intro.races]: intro.md#intro.races
 
785
  [over.match]: over.md#over.match
786
  [over.over]: over.md#over.over
787
- [propagation]: language.md#propagation
788
  [stmt.jump]: stmt.md#stmt.jump
 
789
  [stmt.return]: stmt.md#stmt.return
790
- [stmt.stmt]: stmt.md#stmt.stmt
791
  [structure.specifications]: library.md#structure.specifications
792
- [support.start.term]: language.md#support.start.term
793
  [temp.explicit]: temp.md#temp.explicit
794
  [thread.condition.condvar]: thread.md#thread.condition.condvar
795
  [thread.condition.condvarany]: thread.md#thread.condition.condvarany
796
  [thread.thread.assign]: thread.md#thread.thread.assign
797
  [thread.thread.constr]: thread.md#thread.thread.constr
798
  [thread.thread.destr]: thread.md#thread.thread.destr
799
- [uncaught.exceptions]: language.md#uncaught.exceptions
 
1
  # Exception handling <a id="except">[[except]]</a>
2
 
3
+ ## Preamble <a id="except.pre">[[except.pre]]</a>
4
+
5
  Exception handling provides a way of transferring control and
6
  information from a point in the execution of a thread to an exception
7
  handler associated with a point previously passed by the execution. A
8
  handler will be invoked only by throwing an exception in code executed
9
  in the handler’s try block or in functions called from the handler’s try
 
24
  handler handler-seqₒₚₜ
25
  ```
26
 
27
  ``` bnf
28
  handler:
29
+ 'catch' '(' exception-declaration ')' compound-statement
30
  ```
31
 
32
  ``` bnf
33
  exception-declaration:
34
  attribute-specifier-seqₒₚₜ type-specifier-seq declarator
35
  attribute-specifier-seqₒₚₜ type-specifier-seq abstract-declaratorₒₚₜ
36
  '...'
37
  ```
38
 
39
  The optional *attribute-specifier-seq* in an *exception-declaration*
40
+ appertains to the parameter of the catch clause [[except.handle]].
41
 
42
+ A *try-block* is a *statement* [[stmt.pre]].
43
 
44
  [*Note 1*: Within this Clause “try block” is taken to mean both
45
  *try-block* and *function-try-block*. — *end note*]
46
 
47
  A `goto` or `switch` statement shall not be used to transfer control
 
49
 
50
  [*Example 1*:
51
 
52
  ``` cpp
53
  void f() {
54
+ goto l1; // error
55
+ goto l2; // error
56
  try {
57
  goto l1; // OK
58
+ goto l2; // error
59
  l1: ;
60
  } catch (...) {
61
  l2: ;
62
+ goto l1; // error
63
  goto l2; // OK
64
  }
65
  }
66
  ```
67
 
 
120
  }
121
  ```
122
 
123
  — *end example*]
124
 
125
+ In this Clause, “before” and “after” refer to the “sequenced before”
126
+ relation [[intro.execution]].
127
 
128
  ## Throwing an exception <a id="except.throw">[[except.throw]]</a>
129
 
130
  Throwing an exception transfers control to a handler.
131
 
132
  [*Note 1*: An exception can be thrown from one of the following
133
+ contexts: *throw-expression*s [[expr.throw]], allocation functions
134
+ [[basic.stc.dynamic.allocation]], `dynamic_cast` [[expr.dynamic.cast]],
135
+ `typeid` [[expr.typeid]], *new-expression*s [[expr.new]], and standard
136
+ library functions [[structure.specifications]]. *end note*]
 
137
 
138
  An object is passed and the type of that object determines which
139
  handlers can catch it.
140
 
141
  [*Example 1*:
 
178
  ```
179
 
180
  — *end example*]
181
 
182
  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 copy-initializes ([[dcl.init]],
189
+ [[class.copy.ctor]]) a temporary object, called the *exception object*.
190
+ An lvalue denoting the temporary is used to initialize the variable
191
+ declared in the matching *handler* [[except.handle]]. If the type of the
192
+ exception object would be an incomplete type, an abstract class type
193
+ [[class.abstract]], or a pointer to an incomplete type other than
194
+ cv `void` the program is ill-formed.
195
 
196
  The memory for the exception object is allocated in an unspecified way,
197
  except as noted in  [[basic.stc.dynamic.allocation]]. If a handler exits
198
  by rethrowing, control is passed to another handler for the same
199
  exception object. The points of potential destruction for the exception
200
  object are:
201
 
202
  - when an active handler for the exception exits by any means other than
203
  rethrowing, immediately after the destruction of the object (if any)
204
  declared in the *exception-declaration* in the handler;
205
+ - when an object of type `std::exception_ptr` [[propagation]] that
206
  refers to the exception object is destroyed, before the destructor of
207
  `std::exception_ptr` returns.
208
 
209
  Among all points of potential destruction for the exception object,
210
  there is an unspecified last one where the exception object is
211
+ destroyed. All other points happen before that last one [[intro.races]].
 
212
 
213
  [*Note 2*: No other thread synchronization is implied in exception
214
  handling. — *end note*]
215
 
216
  The implementation may then deallocate the memory for the exception
 
221
  see  [[propagation]] and  [[futures]]. — *end note*]
222
 
223
  When the thrown object is a class object, the constructor selected for
224
  the copy-initialization as well as the constructor selected for a
225
  copy-initialization considering the thrown object as an lvalue shall be
226
+ non-deleted and accessible, even if the copy/move operation is elided
227
+ [[class.copy.elision]]. The destructor is potentially invoked
228
+ [[class.dtor]].
229
 
230
  An exception is considered caught when a handler for that exception
231
+ becomes active [[except.handle]].
232
 
233
  [*Note 4*: An exception can have active handlers and still be
234
  considered uncaught if it is rethrown. — *end note*]
235
 
236
+ If the exception handling mechanism handling an uncaught exception
237
+ [[except.uncaught]] directly invokes a function that exits via an
238
+ exception, the function `std::terminate` is called [[except.terminate]].
239
 
240
  [*Example 2*:
241
 
242
  ``` cpp
243
  struct C {
244
  C() { }
245
  C(const C&) {
246
  if (std::uncaught_exceptions()) {
247
+ throw 0; // throw during copy to handler's exception-declaration object[except.handle]
248
  }
249
  }
250
  };
251
 
252
  int main() {
253
  try {
254
+ throw C(); // calls std::terminate if construction of the handler's
255
+ // exception-declaration object is not elided[class.copy.elision]
256
  } catch(C) { }
257
  }
258
  ```
259
 
260
  — *end example*]
261
 
262
+ [*Note 5*:
263
+
264
+ Consequently, destructors should generally catch exceptions and not let
265
+ them propagate.
266
+
267
+ — *end note*]
268
 
269
  ## Constructors and destructors <a id="except.ctor">[[except.ctor]]</a>
270
 
271
  As control passes from the point where an exception is thrown to a
272
+ handler, objects with automatic storage duration are destroyed by a
273
+ process, specified in this subclause, called *stack unwinding*.
274
 
275
+ Each object with automatic storage duration is destroyed if it has been
276
  constructed, but not yet destroyed, since the try block was entered. If
277
  an exception is thrown during the destruction of temporaries or local
278
+ variables for a `return` statement [[stmt.return]], the destructor for
279
+ the returned object (if any) is also invoked. The objects are destroyed
280
+ in the reverse order of the completion of their construction.
281
 
282
  [*Example 1*:
283
 
284
  ``` cpp
285
  struct A { };
 
297
  return {}; // #2
298
  }
299
  ```
300
 
301
  At \#1, the returned object of type `A` is constructed. Then, the local
302
+ variable `b` is destroyed [[stmt.jump]]. Next, the local variable `y` is
303
+ destroyed, causing stack unwinding, resulting in the destruction of the
304
+ returned object, followed by the destruction of the local variable `a`.
305
+ Finally, the returned object is constructed again at \#2.
306
 
307
  — *end example*]
308
 
309
  If the initialization or destruction of an object other than by
310
  delegating constructor is terminated by an exception, the destructor is
311
  invoked for each of the object’s direct subobjects and, for a complete
312
  object, virtual base class subobjects, whose initialization has
313
+ completed [[dcl.init]] and whose destructor has not yet begun execution,
314
+ except that in the case of destruction, the variant members of a
315
+ union-like class are not destroyed.
316
+
317
+ [*Note 1*: If such an object has a reference member that extends the
318
+ lifetime of a temporary object, this ends the lifetime of the reference
319
+ member, so the lifetime of the temporary object is effectively not
320
+ extended. — *end note*]
321
+
322
+ The subobjects are destroyed in the reverse order of the completion of
323
+ their construction. Such destruction is sequenced before entering a
324
+ handler of the *function-try-block* of the constructor or destructor, if
325
+ any.
326
 
327
  If the *compound-statement* of the *function-body* of a delegating
328
  constructor for an object exits via an exception, the object’s
329
  destructor is invoked. Such destruction is sequenced before entering a
330
  handler of the *function-try-block* of a delegating constructor for that
331
  object, if any.
332
 
333
+ [*Note 2*: If the object was allocated by a *new-expression*
334
+ [[expr.new]], the matching deallocation function
335
+ [[basic.stc.dynamic.deallocation]], if any, is called to free the
336
  storage occupied by the object. — *end note*]
337
 
338
  ## Handling an exception <a id="except.handle">[[except.handle]]</a>
339
 
340
  The *exception-declaration* in a *handler* describes the type(s) of
 
353
  - The *handler* is of type cv `T` or cv `T&` and `E` and `T` are the
354
  same type (ignoring the top-level *cv-qualifier*s), or
355
  - the *handler* is of type cv `T` or cv `T&` and `T` is an unambiguous
356
  public base class of `E`, or
357
  - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
358
+ or pointer-to-member type and `E` is a pointer or pointer-to-member
359
  type that can be converted to `T` by one or more of
360
+ - a standard pointer conversion [[conv.ptr]] not involving conversions
361
+ to pointers to private or protected or ambiguous classes
362
+ - a function pointer conversion [[conv.fctptr]]
363
+ - a qualification conversion [[conv.qual]], or
364
  - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
365
+ or pointer-to-member type and `E` is `std::nullptr_t`.
366
 
367
  [*Note 1*: A *throw-expression* whose operand is an integer literal
368
+ with value zero does not match a handler of pointer or pointer-to-member
369
  type. A handler of reference to array or function type is never a match
370
+ for any exception object [[expr.throw]]. — *end note*]
371
 
372
  [*Example 1*:
373
 
374
  ``` cpp
375
  class Matherr { ... virtual void vf(); };
 
409
 
410
  If no match is found among the handlers for a try block, the search for
411
  a matching handler continues in a dynamically surrounding try block of
412
  the same thread.
413
 
414
+ A handler is considered *active* when initialization is complete for the
415
  parameter (if any) of the catch clause.
416
 
417
  [*Note 3*: The stack will have been unwound at that
418
  point. — *end note*]
419
 
420
+ Also, an implicit handler is considered active when the function
421
+ `std::terminate` is entered due to a throw. A handler is no longer
422
+ considered active when the catch clause exits.
423
 
424
  The exception with the most recently activated handler that is still
425
  active is called the *currently handled exception*.
426
 
427
+ If no matching handler is found, the function `std::terminate` is
428
  called; whether or not the stack is unwound before this call to
429
+ `std::terminate` is *implementation-defined* [[except.terminate]].
430
 
431
  Referring to any non-static member or base class of an object in the
432
  handler for a *function-try-block* of a constructor or destructor for
433
  that object results in undefined behavior.
434
 
435
  The scope and lifetime of the parameters of a function or constructor
436
  extend into the handlers of a *function-try-block*.
437
 
438
  Exceptions thrown in destructors of objects with static storage duration
439
  or in constructors of namespace-scope objects with static storage
440
+ duration are not caught by a *function-try-block* on the `main` function
441
+ [[basic.start.main]]. Exceptions thrown in destructors of objects with
442
+ thread storage duration or in constructors of namespace-scope objects
443
+ with thread storage duration are not caught by a *function-try-block* on
444
+ the initial function of the thread.
445
 
446
+ If a `return` statement [[stmt.return]] appears in a handler of the
447
+ *function-try-block* of a constructor, the program is ill-formed.
448
 
449
  The currently handled exception is rethrown if control reaches the end
450
  of a handler of the *function-try-block* of a constructor or destructor.
451
  Otherwise, flowing off the end of the *compound-statement* of a
452
  *handler* of a *function-try-block* is equivalent to flowing off the end
 
454
 
455
  The variable declared by the *exception-declaration*, of type cv `T` or
456
  cv `T&`, is initialized from the exception object, of type `E`, as
457
  follows:
458
 
459
+ - if `T` is a base class of `E`, the variable is copy-initialized
460
+ [[dcl.init]] from the corresponding base class subobject of the
461
  exception object;
462
+ - otherwise, the variable is copy-initialized [[dcl.init]] from the
463
  exception object.
464
 
465
  The lifetime of the variable ends when the handler exits, after the
466
+ destruction of any objects with automatic storage duration initialized
467
+ within the handler.
468
 
469
  When the handler declares an object, any changes to that object will not
470
  affect the exception object. When the handler declares a reference to an
471
  object, any changes to the referenced object are changes to the
472
  exception object and will have effect should that object be rethrown.
 
477
  is called the *exception specification* of the function. If the
478
  predicate is false, the function has a *potentially-throwing exception
479
  specification*, otherwise it has a *non-throwing exception
480
  specification*. The exception specification is either defined
481
  implicitly, or defined explicitly by using a *noexcept-specifier* as a
482
+ suffix of a function declarator [[dcl.fct]].
483
 
484
  ``` bnf
485
  noexcept-specifier:
486
  'noexcept' '(' constant-expression ')'
487
  'noexcept'
 
488
  ```
489
 
490
  In a *noexcept-specifier*, the *constant-expression*, if supplied, shall
491
+ be a contextually converted constant expression of type `bool`
492
+ [[expr.const]]; that constant expression is the exception specification
493
  of the function type in which the *noexcept-specifier* appears. A `(`
494
  token that follows `noexcept` is part of the *noexcept-specifier* and
495
+ does not commence an initializer [[dcl.init]]. The *noexcept-specifier*
496
+ `noexcept` without a *constant-expression* is equivalent to the
497
+ *noexcept-specifier* `noexcept(true)`.
 
 
498
 
499
  If a declaration of a function does not have a *noexcept-specifier*, the
500
  declaration has a potentially throwing exception specification unless it
501
  is a destructor or a deallocation function or is defaulted on its first
502
+ declaration, in which cases the exception specification is as specified
503
  below and no other declaration for that function shall have a
504
+ *noexcept-specifier*. In an explicit instantiation [[temp.explicit]] a
505
+ *noexcept-specifier* may be specified, but is not required. If a
506
  *noexcept-specifier* is specified in an explicit instantiation
507
  directive, the exception specification shall be the same as the
508
  exception specification of all other declarations of that function. A
509
  diagnostic is required only if the exception specifications are not the
510
  same within a single translation unit.
 
523
  virtual void g();
524
  virtual void h() noexcept = delete;
525
  };
526
 
527
  struct D: B {
528
+ void f(); // error
529
  void g() noexcept; // OK
530
  void h() = delete; // OK
531
  };
532
  ```
533
 
 
535
  potentially-throwing exception specification, whereas `B::f` has a
536
  non-throwing exception specification.
537
 
538
  — *end example*]
539
 
540
+ Whenever an exception is thrown and the search for a handler
541
+ [[except.handle]] encounters the outermost block of a function with a
542
+ non-throwing exception specification, the function `std::terminate` is
543
+ called [[except.terminate]].
544
 
545
+ [*Note 1*: An implementation is not permitted to reject an expression
546
+ merely because, when executed, it throws or might throw an exception
547
+ from a function with a non-throwing exception
548
+ specification. — *end note*]
549
 
550
  [*Example 2*:
551
 
552
  ``` cpp
553
  extern void f(); // potentially-throwing
 
561
  The call to `f` is well-formed even though, when called, `f` might throw
562
  an exception.
563
 
564
  — *end example*]
565
 
566
+ An expression E is *potentially-throwing* if
567
 
568
+ - E is a function call [[expr.call]] whose *postfix-expression* has a
569
+ function type, or a pointer-to-function type, with a
570
  potentially-throwing exception specification, or
571
+ - E implicitly invokes a function (such as an overloaded operator, an
572
  allocation function in a *new-expression*, a constructor for a
573
+ function argument, or a destructor if E is a full-expression
574
+ [[intro.execution]]) that is potentially-throwing, or
575
+ - E is a *throw-expression* [[expr.throw]], or
576
+ - E is a `dynamic_cast` expression that casts to a reference type and
577
+ requires a runtime check [[expr.dynamic.cast]], or
578
+ - E is a `typeid` expression applied to a (possibly parenthesized)
579
  built-in unary `*` operator applied to a pointer to a polymorphic
580
+ class type [[expr.typeid]], or
581
+ - any of the immediate subexpressions [[intro.execution]] of E is
582
  potentially-throwing.
583
 
584
  An implicitly-declared constructor for a class `X`, or a constructor
585
  without a *noexcept-specifier* that is defaulted on its first
586
  declaration, has a potentially-throwing exception specification if and
 
593
  expression, or,
594
  - for a default constructor, a default member initializer.
595
 
596
  [*Note 2*: Even though destructors for fully-constructed subobjects are
597
  invoked when an exception is thrown during the execution of a
598
+ constructor [[except.ctor]], their exception specifications do not
599
  contribute to the exception specification of the constructor, because an
600
+ exception thrown from such a destructor would call the function
601
+ `std::terminate` rather than escape the constructor ([[except.throw]],
602
  [[except.terminate]]). — *end note*]
603
 
604
  The exception specification for an implicitly-declared destructor, or a
605
  destructor without a *noexcept-specifier*, is potentially-throwing if
606
  and only if any of the destructors for any of its potentially
607
+ constructed subobjects is potentially-throwing or the destructor is
608
+ virtual and the destructor of any virtual base class is
609
+ potentially-throwing.
610
 
611
  The exception specification for an implicitly-declared assignment
612
  operator, or an assignment-operator without a *noexcept-specifier* that
613
  is defaulted on its first declaration, is potentially-throwing if and
614
  only if the invocation of any assignment operator in the implicit
615
  definition is potentially-throwing.
616
 
617
+ A deallocation function [[basic.stc.dynamic.deallocation]] with no
618
  explicit *noexcept-specifier* has a non-throwing exception
619
  specification.
620
 
621
+ The exception specification for a comparison operator function
622
+ [[over.binary]] without a *noexcept-specifier* that is defaulted on its
623
+ first declaration is potentially-throwing if and only if any expression
624
+ in the implicit definition is potentially-throwing.
625
+
626
  [*Example 3*:
627
 
628
  ``` cpp
629
  struct A {
630
  A(int = (A(5), 0)) noexcept;
631
  A(const A&) noexcept;
632
  A(A&&) noexcept;
633
  ~A();
634
  };
635
  struct B {
636
+ B() noexcept;
637
  B(const B&) = default; // implicit exception specification is noexcept(true)
638
+ B(B&&, int = (throw 42, 0)) noexcept;
639
  ~B() noexcept(false);
640
  };
641
  int n = 7;
642
  struct D : public A, public B {
643
  int * p = new int[n];
 
658
  An exception specification is considered to be *needed* when:
659
 
660
  - in an expression, the function is the unique lookup result or the
661
  selected member of a set of overloaded functions ([[basic.lookup]],
662
  [[over.match]], [[over.over]]);
663
+ - the function is odr-used [[basic.def.odr]] or, if it appears in an
664
  unevaluated operand, would be odr-used if the expression were
665
  potentially-evaluated;
666
  - the exception specification is compared to that of another declaration
667
  (e.g., an explicit specialization or an overriding virtual function);
668
  - the function is defined; or
669
+ - the exception specification is needed for a defaulted function that
670
+ calls the function. \[*Note 3*: A defaulted declaration does not
671
+ require the exception specification of a base member function to be
672
+ evaluated until the implicit exception specification of the derived
673
+ function is needed, but an explicit *noexcept-specifier* needs the
674
+ implicit exception specification to compare against. — *end note*]
 
675
 
676
+ The exception specification of a defaulted function is evaluated as
677
+ described above only when needed; similarly, the *noexcept-specifier* of
678
+ a specialization of a function template or member function of a class
679
+ template is instantiated only when needed.
680
 
681
  ## Special functions <a id="except.special">[[except.special]]</a>
682
 
683
+ The function `std::terminate` [[except.terminate]] is used by the
684
  exception handling mechanism for coping with errors related to the
685
  exception handling mechanism itself. The function
686
+ `std::current_exception()` [[propagation]] and the class
687
+ `std::nested_exception` [[except.nested]] can be used by a program to
688
  capture the currently handled exception.
689
 
690
+ ### The `std::terminate` function <a id="except.terminate">[[except.terminate]]</a>
691
 
692
  In some situations exception handling must be abandoned for less subtle
693
  error handling techniques.
694
 
695
  [*Note 1*:
696
 
697
  These situations are:
698
 
699
  - when the exception handling mechanism, after completing the
700
  initialization of the exception object but before activation of a
701
+ handler for the exception [[except.throw]], calls a function that
702
  exits via an exception, or
703
  - when the exception handling mechanism cannot find a handler for a
704
+ thrown exception [[except.handle]], or
705
+ - when the search for a handler [[except.handle]] encounters the
706
  outermost block of a function with a non-throwing exception
707
+ specification [[except.spec]], or
708
+ - when the destruction of an object during stack unwinding
709
+ [[except.ctor]] terminates by throwing an exception, or
710
  - when initialization of a non-local variable with static or thread
711
+ storage duration [[basic.start.dynamic]] exits via an exception, or
712
  - when destruction of an object with static or thread storage duration
713
+ exits via an exception [[basic.start.term]], or
714
  - when execution of a function registered with `std::atexit` or
715
+ `std::at_quick_exit` exits via an exception [[support.start.term]], or
716
+ - when a *throw-expression* [[expr.throw]] with no operand attempts to
717
+ rethrow an exception and no exception is being handled
718
+ [[except.throw]], or
 
719
  - when the function `std::nested_exception::rethrow_nested` is called
720
+ for an object that has captured no exception [[except.nested]], or
721
  - when execution of the initial function of a thread exits via an
722
+ exception [[thread.thread.constr]], or
723
  - for a parallel algorithm whose `ExecutionPolicy` specifies such
724
  behavior ([[execpol.seq]], [[execpol.par]], [[execpol.parunseq]]),
725
+ when execution of an element access function
726
+ [[algorithms.parallel.defns]] of the parallel algorithm exits via an
727
+ exception [[algorithms.parallel.exceptions]], or
728
+ - when the destructor or the move assignment operator is invoked on an
729
  object of type `std::thread` that refers to a joinable thread (
730
+ [[thread.thread.destr]], [[thread.thread.assign]]), or
731
  - when a call to a `wait()`, `wait_until()`, or `wait_for()` function on
732
+ a condition variable ([[thread.condition.condvar]],
733
  [[thread.condition.condvarany]]) fails to meet a postcondition.
734
 
735
  — *end note*]
736
 
737
+ In such cases, the function `std::terminate` is called
738
+ [[exception.terminate]]. In the situation where no matching handler is
739
+ found, it is *implementation-defined* whether or not the stack is
740
+ unwound before `std::terminate` is called. In the situation where the
741
+ search for a handler [[except.handle]] encounters the outermost block of
742
+ a function with a non-throwing exception specification [[except.spec]],
743
  it is *implementation-defined* whether the stack is unwound, unwound
744
+ partially, or not unwound at all before the function `std::terminate` is
745
+ called. In all other situations, the stack shall not be unwound before
746
+ the function `std::terminate` is called. An implementation is not
747
+ permitted to finish stack unwinding prematurely based on a determination
748
+ that the unwind process will eventually cause a call to the function
749
+ `std::terminate`.
750
 
751
  ### The `std::uncaught_exceptions()` function <a id="except.uncaught">[[except.uncaught]]</a>
752
 
753
  An exception is considered uncaught after completing the initialization
754
+ of the exception object [[except.throw]] until completing the activation
755
+ of a handler for the exception [[except.handle]].
756
+
757
+ [*Note 1*: As a consequence, an exception is considered uncaught during
758
+ any stack unwinding resulting from it being thrown. *end note*]
759
+
760
+ If an exception is rethrown ([[expr.throw]], [[propagation]]), it is
761
+ considered uncaught from the point of rethrow until the rethrown
762
+ exception is caught. The function `std::uncaught_exceptions()`
763
+ [[uncaught.exceptions]] returns the number of uncaught exceptions in the
764
+ current thread.
765
 
766
  <!-- Link reference definitions -->
767
  [algorithms.parallel.defns]: algorithms.md#algorithms.parallel.defns
768
  [algorithms.parallel.exceptions]: algorithms.md#algorithms.parallel.exceptions
769
  [basic.def.odr]: basic.md#basic.def.odr
 
771
  [basic.start.dynamic]: basic.md#basic.start.dynamic
772
  [basic.start.main]: basic.md#basic.start.main
773
  [basic.start.term]: basic.md#basic.start.term
774
  [basic.stc.dynamic.allocation]: basic.md#basic.stc.dynamic.allocation
775
  [basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
776
+ [class.abstract]: class.md#class.abstract
777
+ [class.copy.ctor]: class.md#class.copy.ctor
778
+ [class.copy.elision]: class.md#class.copy.elision
779
+ [class.dtor]: class.md#class.dtor
780
+ [conv.fctptr]: expr.md#conv.fctptr
781
+ [conv.ptr]: expr.md#conv.ptr
782
+ [conv.qual]: expr.md#conv.qual
783
  [dcl.fct]: dcl.md#dcl.fct
784
  [dcl.init]: dcl.md#dcl.init
 
785
  [except]: #except
786
  [except.ctor]: #except.ctor
787
  [except.handle]: #except.handle
788
+ [except.nested]: support.md#except.nested
789
+ [except.pre]: #except.pre
790
  [except.spec]: #except.spec
791
  [except.special]: #except.special
792
  [except.terminate]: #except.terminate
793
  [except.throw]: #except.throw
794
  [except.uncaught]: #except.uncaught
795
+ [exception.terminate]: support.md#exception.terminate
796
  [execpol.par]: utilities.md#execpol.par
797
  [execpol.parunseq]: utilities.md#execpol.parunseq
798
  [execpol.seq]: utilities.md#execpol.seq
799
  [expr.call]: expr.md#expr.call
800
  [expr.const]: expr.md#expr.const
801
  [expr.dynamic.cast]: expr.md#expr.dynamic.cast
802
  [expr.new]: expr.md#expr.new
803
  [expr.throw]: expr.md#expr.throw
804
  [expr.typeid]: expr.md#expr.typeid
805
  [futures]: thread.md#futures
806
+ [intro.execution]: basic.md#intro.execution
807
+ [intro.races]: basic.md#intro.races
808
+ [over.binary]: over.md#over.binary
809
  [over.match]: over.md#over.match
810
  [over.over]: over.md#over.over
811
+ [propagation]: support.md#propagation
812
  [stmt.jump]: stmt.md#stmt.jump
813
+ [stmt.pre]: stmt.md#stmt.pre
814
  [stmt.return]: stmt.md#stmt.return
 
815
  [structure.specifications]: library.md#structure.specifications
816
+ [support.start.term]: support.md#support.start.term
817
  [temp.explicit]: temp.md#temp.explicit
818
  [thread.condition.condvar]: thread.md#thread.condition.condvar
819
  [thread.condition.condvarany]: thread.md#thread.condition.condvarany
820
  [thread.thread.assign]: thread.md#thread.thread.assign
821
  [thread.thread.constr]: thread.md#thread.thread.constr
822
  [thread.thread.destr]: thread.md#thread.thread.destr
823
+ [uncaught.exceptions]: support.md#uncaught.exceptions