Да. Исключение активно до тех пор, пока оно не будет перехвачено, где оно становится неактивным. Но он живет, пока не закончится область действия обработчика . От стандарта, акцент мой:
§15.1 / 4: Память для временной копии создаваемого исключения распределяется неуказанным образом, за исключением случаев, указанных в 3.7.4.1. Временное состояние сохраняется до тех пор, пока для этого исключения выполняется обработчик.
То есть:
catch(...)
{ // <--
/* ... */
} // <--
Между этими стрелками вы можете повторно выдать исключение. Только когда заканчивается область действия обработчиков, исключение перестает существовать.
Фактически, в §15.1 / 6 приведенный пример почти совпадает с вашим кодом:
try {
// ...
}
catch (...) { // catch all exceptions
// respond (partially) to exception <-- ! :D
throw; //pass the exception to some
// other handler
}
Имейте в виду, если вам throw
без активного исключения будет вызван terminate
. Это не может иметь место для вас, находясь в обработчике.
Если выдает doSomethingElse()
и исключение не имеет соответствующего обработчика, поскольку исходное исключение считается обработанным, новое исключение заменит его. (Как будто он только что выбросил, начинает разматывать стопку и т. Д.)
То есть:
void doSomethingElse(void)
{
try
{
throw "this is fine";
}
catch(...)
{
// the previous exception dies, back to
// using the original exception
}
try
{
// rethrow the exception that was
// active when doSomethingElse was called
throw;
}
catch (...)
{
throw; // and let it go again
}
throw "this replaces the old exception";
// this new one takes over, begins stack unwinding
// leaves the catch's scope, old exception is done living,
// and now back to normal exception stuff
}
try
{
throw "original exception";
}
catch (...)
{
doSomethingElse();
throw; // this won't actually be reached,
// the new exception has begun propagating
}
Конечно, если ничего не сработает, будет достигнуто throw;
, и вы выбросите пойманную исключительную ситуацию, как и ожидалось.