tmp/tmp3azvie3g/{from.md → to.md}
RENAMED
|
@@ -1,10 +1,14 @@
|
|
| 1 |
## Throwing an exception <a id="except.throw">[[except.throw]]</a>
|
| 2 |
|
| 3 |
-
Throwing an exception transfers control to a handler. An
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
``` cpp
|
| 8 |
throw "Help!";
|
| 9 |
```
|
| 10 |
|
|
@@ -46,23 +50,21 @@ When an exception is thrown, control is transferred to the nearest
|
|
| 46 |
handler with a matching type ([[except.handle]]); “nearest” means the
|
| 47 |
handler for which the *compound-statement* or *ctor-initializer*
|
| 48 |
following the `try` keyword was most recently entered by the thread of
|
| 49 |
control and not yet exited.
|
| 50 |
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
type of the exception object
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
treated exactly as a function argument in a call ([[expr.call]]) or the
|
| 63 |
-
operand of a return statement.
|
| 64 |
|
| 65 |
The memory for the exception object is allocated in an unspecified way,
|
| 66 |
except as noted in [[basic.stc.dynamic.allocation]]. If a handler exits
|
| 67 |
by rethrowing, control is passed to another handler for the same
|
| 68 |
exception. The exception object is destroyed after either the last
|
|
@@ -73,43 +75,48 @@ whichever is later. In the former case, the destruction occurs when the
|
|
| 73 |
handler exits, immediately after the destruction of the object declared
|
| 74 |
in the *exception-declaration* in the handler, if any. In the latter
|
| 75 |
case, the destruction occurs before the destructor of
|
| 76 |
`std::exception_ptr` returns. The implementation may then deallocate the
|
| 77 |
memory for the exception object; any such deallocation is done in an
|
| 78 |
-
unspecified way.
|
| 79 |
-
|
| 80 |
-
|
| 81 |
|
| 82 |
-
When the thrown object is a class object, the
|
| 83 |
-
the destructor shall be accessible, even if
|
| 84 |
-
elided ([[class.copy]]).
|
| 85 |
|
| 86 |
An exception is considered caught when a handler for that exception
|
| 87 |
becomes active ([[except.handle]]). An exception can have active
|
| 88 |
handlers and still be considered uncaught if it is rethrown.
|
| 89 |
|
| 90 |
-
If the exception handling mechanism, after completing
|
| 91 |
-
|
| 92 |
-
function that exits via an exception,
|
| 93 |
-
[[except.terminate]]).
|
| 94 |
|
| 95 |
``` cpp
|
| 96 |
struct C {
|
| 97 |
C() { }
|
| 98 |
-
C(const C&) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
};
|
| 100 |
|
| 101 |
int main() {
|
| 102 |
try {
|
| 103 |
-
throw C(); // calls std::terminate()
|
|
|
|
| 104 |
} catch(C) { }
|
| 105 |
}
|
| 106 |
```
|
| 107 |
|
| 108 |
A *throw-expression* with no operand rethrows the currently handled
|
| 109 |
exception ([[except.handle]]). The exception is reactivated with the
|
| 110 |
-
existing
|
| 111 |
exception is no longer considered to be caught; therefore, the value of
|
| 112 |
`std::uncaught_exception()` will again be `true`. code that must be
|
| 113 |
executed because of an exception yet cannot completely handle the
|
| 114 |
exception can be written like this:
|
| 115 |
|
|
|
|
| 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 |
|
|
|
|
| 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
|
|
|
|
| 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 |
|
| 107 |
int main() {
|
| 108 |
try {
|
| 109 |
+
throw C(); // calls std::terminate() if construction of the handler's
|
| 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 |
|