Если в моем коде есть следующий фрагмент:
try {
doSomething();
} catch (...) {
doSomethingElse();
throw;
}
Будет ли бросок бросить конкретное исключение, пойманное эллипсовым обработчиком по умолчанию?
Если в моем коде есть следующий фрагмент:
try {
doSomething();
} catch (...) {
doSomethingElse();
throw;
}
Будет ли бросок бросить конкретное исключение, пойманное эллипсовым обработчиком по умолчанию?
Да. Исключение активно до тех пор, пока оно не поймается, когда оно станет неактивным. Но он живет до тех пор, пока не закончится область действия обработчика. Из стандарта основное внимание уделяется:
§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 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;
будет достигнуто, и вы бросите свое пойманное исключение, как ожидалось.