From Jason Turner

[except.throw]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpio5qyobj/{from.md → to.md} +61 -59
tmp/tmpio5qyobj/{from.md → to.md} RENAMED
@@ -1,26 +1,31 @@
1
  ## Throwing an exception <a id="except.throw">[[except.throw]]</a>
2
 
3
- Throwing an exception transfers control to a handler. An exception can
4
- be thrown from one of the following contexts: *throw-expression* (see
5
- below), allocation functions ([[basic.stc.dynamic.allocation]]),
6
- `dynamic_cast` ([[expr.dynamic.cast]]), `typeid` ([[expr.typeid]]),
7
- *new-expression* ([[expr.new]]), and standard library functions (
8
- [[structure.specifications]]). An object is passed and the type of that
9
- object determines which handlers can catch it.
 
 
 
 
 
 
10
 
11
  ``` cpp
12
  throw "Help!";
13
  ```
14
 
15
  can be caught by a *handler* of `const` `char*` type:
16
 
17
  ``` cpp
18
  try {
19
  // ...
20
- }
21
- catch(const char* p) {
22
  // handle character string exceptions here
23
  }
24
  ```
25
 
26
  and
@@ -34,73 +39,87 @@ public:
34
  void f(double x) {
35
  throw Overflow('+',x,3.45e107);
36
  }
37
  ```
38
 
39
- can be caught by a handler for exceptions of type `Overflow`
40
 
41
  ``` cpp
42
  try {
43
  f(1.2);
44
  } catch(Overflow& oo) {
45
  // handle exceptions of type Overflow here
46
  }
47
  ```
48
 
 
 
49
  When an exception is thrown, control is transferred to the nearest
50
  handler with a matching type ([[except.handle]]); “nearest” means the
51
  handler for which the *compound-statement* or *ctor-initializer*
52
  following the `try` keyword was most recently entered by the thread of
53
  control and not yet exited.
54
 
55
  Throwing an exception copy-initializes ([[dcl.init]], [[class.copy]]) a
56
- temporary object, called the *exception object*. The temporary is an
57
- lvalue and is used to initialize the variable declared in the matching
58
  *handler* ([[except.handle]]). If the type of the exception object
59
  would be an incomplete type or a pointer to an incomplete type other
60
- than (possibly cv-qualified) `void` the program is ill-formed.
61
- Evaluating a *throw-expression* with an operand throws an exception; the
62
- type of the exception object is determined by removing any top-level
63
- *cv-qualifiers* from the static type of the operand and adjusting the
64
- type from “array of `T`” or “function returning `T`” to “pointer to `T`”
65
- or “pointer to function returning `T`,” respectively.
66
 
67
  The memory for the exception object is allocated in an unspecified way,
68
  except as noted in  [[basic.stc.dynamic.allocation]]. If a handler exits
69
  by rethrowing, control is passed to another handler for the same
70
- exception. The exception object is destroyed after either the last
71
- remaining active handler for the exception exits by any means other than
72
- rethrowing, or the last object of type `std::exception_ptr` (
73
- [[propagation]]) that refers to the exception object is destroyed,
74
- whichever is later. In the former case, the destruction occurs when the
75
- handler exits, immediately after the destruction of the object declared
76
- in the *exception-declaration* in the handler, if any. In the latter
77
- case, the destruction occurs before the destructor of
78
- `std::exception_ptr` returns. The implementation may then deallocate the
79
- memory for the exception object; any such deallocation is done in an
80
- unspecified way. a thrown exception does not propagate to other threads
 
 
 
 
 
 
 
 
 
 
 
81
  unless caught, stored, and rethrown using appropriate library functions;
82
- see  [[propagation]] and  [[futures]].
83
 
84
  When the thrown object is a class object, the constructor selected for
85
- the copy-initialization and the destructor shall be accessible, even if
86
- the copy/move operation is elided ([[class.copy]]).
 
 
 
87
 
88
  An exception is considered caught when a handler for that exception
89
- becomes active ([[except.handle]]). An exception can have active
90
- handlers and still be considered uncaught if it is rethrown.
91
 
92
- If the exception handling mechanism, after completing the initialization
93
- of the exception object but before the activation of a handler for the
94
- exception, calls a function that exits via an exception,
95
- `std::terminate` is called ([[except.terminate]]).
 
 
 
 
96
 
97
  ``` cpp
98
  struct C {
99
  C() { }
100
  C(const C&) {
101
- if (std::uncaught_exception()) {
102
  throw 0; // throw during copy to handler's exception-declaration object~([except.handle])
103
  }
104
  }
105
  };
106
 
@@ -110,27 +129,10 @@ int main() {
110
  // exception-declaration object is not elided~([class.copy])
111
  } catch(C) { }
112
  }
113
  ```
114
 
115
- A *throw-expression* with no operand rethrows the currently handled
116
- exception ([[except.handle]]). The exception is reactivated with the
117
- existing exception object; no new exception object is created. The
118
- exception is no longer considered to be caught; therefore, the value of
119
- `std::uncaught_exception()` will again be `true`. code that must be
120
- executed because of an exception yet cannot completely handle the
121
- exception can be written like this:
122
 
123
- ``` cpp
124
- try {
125
- // ...
126
- } catch (...) { // catch all exceptions
127
- // respond (partially) to exception
128
- throw; // pass the exception to some
129
- // other handler
130
- }
131
- ```
132
-
133
- If no exception is presently being handled, executing a
134
- *throw-expression* with no operand calls `std::terminate()` (
135
- [[except.terminate]]).
136
 
 
1
  ## Throwing an exception <a id="except.throw">[[except.throw]]</a>
2
 
3
+ Throwing an exception transfers control to a handler.
4
+
5
+ [*Note 1*: An exception can be thrown from one of the following
6
+ contexts: *throw-expression*s ([[expr.throw]]), allocation functions (
7
+ [[basic.stc.dynamic.allocation]]), `dynamic_cast` (
8
+ [[expr.dynamic.cast]]), `typeid` ([[expr.typeid]]), *new-expression*s (
9
+ [[expr.new]]), and standard library functions (
10
+ [[structure.specifications]]). — *end note*]
11
+
12
+ An object is passed and the type of that object determines which
13
+ handlers can catch it.
14
+
15
+ [*Example 1*:
16
 
17
  ``` cpp
18
  throw "Help!";
19
  ```
20
 
21
  can be caught by a *handler* of `const` `char*` type:
22
 
23
  ``` cpp
24
  try {
25
  // ...
26
+ } catch(const char* p) {
 
27
  // handle character string exceptions here
28
  }
29
  ```
30
 
31
  and
 
39
  void f(double x) {
40
  throw Overflow('+',x,3.45e107);
41
  }
42
  ```
43
 
44
+ can be caught by a handler for exceptions of type `Overflow`:
45
 
46
  ``` cpp
47
  try {
48
  f(1.2);
49
  } catch(Overflow& oo) {
50
  // handle exceptions of type Overflow here
51
  }
52
  ```
53
 
54
+ — *end example*]
55
+
56
  When an exception is thrown, control is transferred to the nearest
57
  handler with a matching type ([[except.handle]]); “nearest” means the
58
  handler for which the *compound-statement* or *ctor-initializer*
59
  following the `try` keyword was most recently entered by the thread of
60
  control and not yet exited.
61
 
62
  Throwing an exception copy-initializes ([[dcl.init]], [[class.copy]]) a
63
+ temporary object, called the *exception object*. An lvalue denoting the
64
+ temporary is used to initialize the variable declared in the matching
65
  *handler* ([[except.handle]]). If the type of the exception object
66
  would be an incomplete type or a pointer to an incomplete type other
67
+ than cv `void` the program is ill-formed.
 
 
 
 
 
68
 
69
  The memory for the exception object is allocated in an unspecified way,
70
  except as noted in  [[basic.stc.dynamic.allocation]]. If a handler exits
71
  by rethrowing, control is passed to another handler for the same
72
+ exception object. The points of potential destruction for the exception
73
+ object are:
74
+
75
+ - when an active handler for the exception exits by any means other than
76
+ rethrowing, immediately after the destruction of the object (if any)
77
+ declared in the *exception-declaration* in the handler;
78
+ - when an object of type `std::exception_ptr` ([[propagation]]) that
79
+ refers to the exception object is destroyed, before the destructor of
80
+ `std::exception_ptr` returns.
81
+
82
+ Among all points of potential destruction for the exception object,
83
+ there is an unspecified last one where the exception object is
84
+ destroyed. All other points happen before that last one (
85
+ [[intro.races]]).
86
+
87
+ [*Note 2*: No other thread synchronization is implied in exception
88
+ handling. — *end note*]
89
+
90
+ The implementation may then deallocate the memory for the exception
91
+ object; any such deallocation is done in an unspecified way.
92
+
93
+ [*Note 3*: A thrown exception does not propagate to other threads
94
  unless caught, stored, and rethrown using appropriate library functions;
95
+ see  [[propagation]] and  [[futures]]. — *end note*]
96
 
97
  When the thrown object is a class object, the constructor selected for
98
+ the copy-initialization as well as the constructor selected for a
99
+ copy-initialization considering the thrown object as an lvalue shall be
100
+ non-deleted and accessible, even if the copy/move operation is elided (
101
+ [[class.copy]]). The destructor is potentially invoked (
102
+ [[class.dtor]]).
103
 
104
  An exception is considered caught when a handler for that exception
105
+ becomes active ([[except.handle]]).
 
106
 
107
+ [*Note 4*: An exception can have active handlers and still be
108
+ considered uncaught if it is rethrown. *end note*]
109
+
110
+ If the exception handling mechanism handling an uncaught exception (
111
+ [[except.uncaught]]) directly invokes a function that exits via an
112
+ exception, `std::terminate` is called ([[except.terminate]]).
113
+
114
+ [*Example 2*:
115
 
116
  ``` cpp
117
  struct C {
118
  C() { }
119
  C(const C&) {
120
+ if (std::uncaught_exceptions()) {
121
  throw 0; // throw during copy to handler's exception-declaration object~([except.handle])
122
  }
123
  }
124
  };
125
 
 
129
  // exception-declaration object is not elided~([class.copy])
130
  } catch(C) { }
131
  }
132
  ```
133
 
134
+ *end example*]
 
 
 
 
 
 
135
 
136
+ [*Note 5*: Consequently, destructors should generally catch exceptions
137
+ and not let them propagate. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
138