From Jason Turner

[except.handle]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3y_fbntr/{from.md → to.md} +48 -49
tmp/tmp3y_fbntr/{from.md → to.md} RENAMED
@@ -6,37 +6,41 @@ exceptions that can cause that *handler* to be entered. The
6
  class type, or an rvalue reference type. The *exception-declaration*
7
  shall not denote a pointer or reference to an incomplete type, other
8
  than `void*`, `const` `void*`, `volatile` `void*`, or `const` `volatile`
9
  `void*`.
10
 
11
- A handler of type “array of `T`” or function returning `T` is adjusted
12
- to be of type “pointer to `T`” or “pointer to function returning `T`”,
13
- respectively.
14
 
15
  A *handler* is a match for an exception object of type `E` if
16
 
17
- - The *handler* is of type *cv* `T` or *cv* `T&` and `E` and `T` are the
18
- same type (ignoring the top-level *cv-qualifiers*), or
19
- - the *handler* is of type *cv* `T` or *cv* `T&` and `T` is an
20
- unambiguous public base class of `E`, or
21
- - the *handler* is of type *cv* `T` or `const T&` where `T` is a pointer
22
- type and `E` is a pointer type that can be converted to `T` by either
23
- or both of
24
  - a standard pointer conversion ([[conv.ptr]]) not involving
25
  conversions to pointers to private or protected or ambiguous classes
26
- - a qualification conversion, or
27
- - the *handler* is of type *cv* `T` or `const T&` where `T` is a pointer
 
28
  or pointer to member type and `E` is `std::nullptr_t`.
29
 
30
- A *throw-expression* whose operand is an integer literal with value zero
31
- does not match a handler of pointer or pointer to member type.
 
 
 
 
32
 
33
  ``` cpp
34
- class Matherr { /* ... */ virtual void vf(); };
35
- class Overflow: public Matherr { /* ... */ };
36
- class Underflow: public Matherr { /* ... */ };
37
- class Zerodivide: public Matherr { /* ... */ };
38
 
39
  void f() {
40
  try {
41
  g();
42
  } catch (Overflow oo) {
@@ -50,14 +54,18 @@ void f() {
50
  Here, the `Overflow` handler will catch exceptions of type `Overflow`
51
  and the `Matherr` handler will catch exceptions of type `Matherr` and of
52
  all types publicly derived from `Matherr` including exceptions of type
53
  `Underflow` and `Zerodivide`.
54
 
55
- The handlers for a try block are tried in order of appearance. That
56
- makes it possible to write handlers that can never be executed, for
57
- example by placing a handler for a derived class after a handler for a
58
- corresponding base class.
 
 
 
 
59
 
60
  A `...` in a handler’s *exception-declaration* functions similarly to
61
  `...` in a function parameter declaration; it specifies a match for any
62
  exception. If present, a `...` handler shall be the last handler for its
63
  try block.
@@ -65,15 +73,18 @@ try block.
65
  If no match is found among the handlers for a try block, the search for
66
  a matching handler continues in a dynamically surrounding try block of
67
  the same thread.
68
 
69
  A handler is considered active when initialization is complete for the
70
- parameter (if any) of the catch clause. The stack will have been unwound
71
- at that point. Also, an implicit handler is considered active when
72
- `std::terminate()` or `std::unexpected()` is entered due to a throw. A
73
- handler is no longer considered active when the catch clause exits or
74
- when `std::unexpected()` exits after being entered due to a throw.
 
 
 
75
 
76
  The exception with the most recently activated handler that is still
77
  active is called the *currently handled exception*.
78
 
79
  If no matching handler is found, the function `std::terminate()` is
@@ -82,44 +93,32 @@ called; whether or not the stack is unwound before this call to
82
 
83
  Referring to any non-static member or base class of an object in the
84
  handler for a *function-try-block* of a constructor or destructor for
85
  that object results in undefined behavior.
86
 
87
- The fully constructed base classes and members of an object shall be
88
- destroyed before entering the handler of a *function-try-block* of a
89
- constructor for that object. Similarly, if a delegating constructor for
90
- an object exits with an exception after the non-delegating constructor
91
- for that object has completed execution, the object’s destructor shall
92
- be executed before entering the handler of a of a constructor for that
93
- object. The base classes and non-variant members of an object shall be
94
- destroyed before entering the handler of a of a destructor for that
95
- object ([[class.dtor]]).
96
-
97
  The scope and lifetime of the parameters of a function or constructor
98
  extend into the handlers of a *function-try-block*.
99
 
100
  Exceptions thrown in destructors of objects with static storage duration
101
  or in constructors of namespace-scope objects with static storage
102
- duration are not caught by a *function-try-block* on `main()`.
103
- Exceptions thrown in destructors of objects with thread storage duration
104
- or in constructors of namespace-scope objects with thread storage
105
- duration are not caught by a *function-try-block* on the initial
106
- function of the thread.
107
 
108
  If a return statement appears in a handler of the *function-try-block*
109
  of a constructor, the program is ill-formed.
110
 
111
  The currently handled exception is rethrown if control reaches the end
112
  of a handler of the *function-try-block* of a constructor or destructor.
113
- Otherwise, a function returns when control reaches the end of a handler
114
- for the *function-try-block* ([[stmt.return]]). Flowing off the end of
115
- a *function-try-block* is equivalent to a `return` with no value; this
116
- results in undefined behavior in a value-returning function (
117
- [[stmt.return]]).
118
 
119
- The variable declared by the *exception-declaration*, of type cv `T` or
120
- cv `T&`, is initialized from the exception object, of type `E`, as
121
  follows:
122
 
123
  - if `T` is a base class of `E`, the variable is copy-initialized (
124
  [[dcl.init]]) from the corresponding base class subobject of the
125
  exception object;
 
6
  class type, or an rvalue reference type. The *exception-declaration*
7
  shall not denote a pointer or reference to an incomplete type, other
8
  than `void*`, `const` `void*`, `volatile` `void*`, or `const` `volatile`
9
  `void*`.
10
 
11
+ A handler of type “array of `T`” or function type `T` is adjusted to be
12
+ of type “pointer to `T`”.
 
13
 
14
  A *handler* is a match for an exception object of type `E` if
15
 
16
+ - The *handler* is of type cv `T` or cv `T&` and `E` and `T` are the
17
+ same type (ignoring the top-level *cv-qualifier*s), or
18
+ - the *handler* is of type cv `T` or cv `T&` and `T` is an unambiguous
19
+ public base class of `E`, or
20
+ - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
21
+ or pointer to member type and `E` is a pointer or pointer to member
22
+ type that can be converted to `T` by one or more of
23
  - a standard pointer conversion ([[conv.ptr]]) not involving
24
  conversions to pointers to private or protected or ambiguous classes
25
+ - a function pointer conversion ([[conv.fctptr]])
26
+ - a qualification conversion ([[conv.qual]]), or
27
+ - the *handler* is of type cv `T` or `const T&` where `T` is a pointer
28
  or pointer to member type and `E` is `std::nullptr_t`.
29
 
30
+ [*Note 1*: A *throw-expression* whose operand is an integer literal
31
+ with value zero does not match a handler of pointer or pointer to member
32
+ type. A handler of reference to array or function type is never a match
33
+ for any exception object ([[expr.throw]]). — *end note*]
34
+
35
+ [*Example 1*:
36
 
37
  ``` cpp
38
+ class Matherr { ... virtual void vf(); };
39
+ class Overflow: public Matherr { ... };
40
+ class Underflow: public Matherr { ... };
41
+ class Zerodivide: public Matherr { ... };
42
 
43
  void f() {
44
  try {
45
  g();
46
  } catch (Overflow oo) {
 
54
  Here, the `Overflow` handler will catch exceptions of type `Overflow`
55
  and the `Matherr` handler will catch exceptions of type `Matherr` and of
56
  all types publicly derived from `Matherr` including exceptions of type
57
  `Underflow` and `Zerodivide`.
58
 
59
+ *end example*]
60
+
61
+ The handlers for a try block are tried in order of appearance.
62
+
63
+ [*Note 2*: This makes it possible to write handlers that can never be
64
+ executed, for example by placing a handler for a final derived class
65
+ after a handler for a corresponding unambiguous public base
66
+ class. — *end note*]
67
 
68
  A `...` in a handler’s *exception-declaration* functions similarly to
69
  `...` in a function parameter declaration; it specifies a match for any
70
  exception. If present, a `...` handler shall be the last handler for its
71
  try block.
 
73
  If no match is found among the handlers for a try block, the search for
74
  a matching handler continues in a dynamically surrounding try block of
75
  the same thread.
76
 
77
  A handler is considered active when initialization is complete for the
78
+ parameter (if any) of the catch clause.
79
+
80
+ [*Note 3*: The stack will have been unwound at that
81
+ point. *end note*]
82
+
83
+ Also, an implicit handler is considered active when `std::terminate()`
84
+ is entered due to a throw. A handler is no longer considered active when
85
+ the catch clause exits.
86
 
87
  The exception with the most recently activated handler that is still
88
  active is called the *currently handled exception*.
89
 
90
  If no matching handler is found, the function `std::terminate()` is
 
93
 
94
  Referring to any non-static member or base class of an object in the
95
  handler for a *function-try-block* of a constructor or destructor for
96
  that object results in undefined behavior.
97
 
 
 
 
 
 
 
 
 
 
 
98
  The scope and lifetime of the parameters of a function or constructor
99
  extend into the handlers of a *function-try-block*.
100
 
101
  Exceptions thrown in destructors of objects with static storage duration
102
  or in constructors of namespace-scope objects with static storage
103
+ duration are not caught by a *function-try-block* on the `main`
104
+ function ([[basic.start.main]]). Exceptions thrown in destructors of
105
+ objects with thread storage duration or in constructors of
106
+ namespace-scope objects with thread storage duration are not caught by a
107
+ *function-try-block* on the initial function of the thread.
108
 
109
  If a return statement appears in a handler of the *function-try-block*
110
  of a constructor, the program is ill-formed.
111
 
112
  The currently handled exception is rethrown if control reaches the end
113
  of a handler of the *function-try-block* of a constructor or destructor.
114
+ Otherwise, flowing off the end of the *compound-statement* of a
115
+ *handler* of a *function-try-block* is equivalent to flowing off the end
116
+ of the *compound-statement* of that function (see [[stmt.return]]).
 
 
117
 
118
+ The variable declared by the *exception-declaration*, of type cv `T` or
119
+ cv `T&`, is initialized from the exception object, of type `E`, as
120
  follows:
121
 
122
  - if `T` is a base class of `E`, the variable is copy-initialized (
123
  [[dcl.init]]) from the corresponding base class subobject of the
124
  exception object;