Подтвердить что ты не робот

Выбрасывает внутри эллипсиса catch (...) реконструирует исходную ошибку в С++?

Если в моем коде есть следующий фрагмент:

try {
  doSomething();
} catch (...) {
  doSomethingElse();
  throw;
}

Будет ли бросок бросить конкретное исключение, пойманное эллипсовым обработчиком по умолчанию?

4b9b3361

Ответ 1

Да. Исключение активно до тех пор, пока оно не поймается, когда оно станет неактивным. Но он живет до тех пор, пока не закончится область действия обработчика. Из стандарта основное внимание уделяется:

§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; будет достигнуто, и вы бросите свое пойманное исключение, как ожидалось.