Действительно бросает в замещающем знаке выгоды (…), повторно бросают исходную ошибку в C++?

Если в моем коде у меня есть следующий отрывок:

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

Бросок повторно бросит определенное исключение, пойманное обработчиком замещающих знаков по умолчанию?

29
задан Doorknob 15 December 2014 в 19:13
поделиться

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
}

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


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

38
ответ дан 28 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: