2

Рассмотрим следующий код:

try
{
    throw _1();
}
catch (...)
{
    try
    {
        throw _2();
    }
    catch (...)
    {
        throw _3();
    }
    throw;
}

Я хочу понять следующее:

1) Что именно происходит, когда случается throw _2;? Активное исключение (_1) заменяется другим (_2)?

2) Какое именно исключение будет проброшено дальше при вызове throw;?

3) Если throw _3; не будет, то будет ли что-нибудь проброшено дальше?

5
  • 1
    Посмотрите на примере. throw _3 случается и вызывается std::terminate.
    – ВЛ 80
    18 дек 2019 в 14:33
  • std::terminate() вызывается в том случае, если ловить исключение больше некому, а, допустим, это не так.
    – MGNeo
    18 дек 2019 в 14:38
  • 1
    Сделаем новый пример с ещё одним try-catch - тогда есть кому ловить. throw _3 случается и ловится. До пустого throw исполнение не доходит.
    – ВЛ 80
    18 дек 2019 в 14:42
  • 1) что такое активное исключенние? первый кэтч словит _1 и бросит _2 2) throw вызван не будет 3) да, проброшено будет _1. 18 дек 2019 в 14:56
  • throw - работает схоже как return или goto, только передаёт управление в ближайший catch именно той обвертки try-catch, где это случилось. Если в текущем методе такой обвертки нету - берется обвертка из функции которая вызвала данную, и функция функции вызвавшей данную - так сканируется весь стек-трейс до встречи try-catch. Если соответствующий try-catch не встетился - идет аварийный выход.
    – nick_n_a
    18 дек 2019 в 15:29

1 ответ 1

5

Здесь нет никакой необходимости "заменять" активное исключение. Механизмы обработки исключений прекрасно "вкладываются" друг в друга. throw _2(); выбрасывает свое, независимое исключение. Если бы это исключение не ловилось сразу внутри первого обработчика, а вылетало бы за его пределы, то исключение _1 бы деструктировалось при выходе из обработчика, ибо его обработка завершена. А исключение _2 летело бы дальше.

В вашем же варианте после throw _3();, исключение _2 ловится вторым обработчиком и деструктируется при выходе из этого второго обработчика, а исключение _1 деструктируется при выходе из первого обработчика - их обработка завершена. А исключение _3 летит дальше.

Если же вы в своем коде уберете throw _3();, то после завершения обработки _2 через посредство throw; будет перевыброшено _1.

В текущем состоянии кода из-за throw _3(); управление никогда не дойдет до throw;

1
  • Большое вам спасибо за помощь.
    – MGNeo
    19 дек 2019 в 7:18

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.