Разбрасывает ли бросок внутри многоточия (...) исходную ошибку в C ++? - PullRequest
29 голосов
/ 19 марта 2010

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

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

Сгенерирует ли бросок конкретное исключение, перехваченное обработчиком многоточия по умолчанию?

1 Ответ

38 голосов
/ 19 марта 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...