Будет ли C ++ бросить без аргументов, работающих внутри другого рама, чтобы разобрать исключение?

StackOverflow https://stackoverflow.com/questions/3561571

  •  01-10-2019
  •  | 
  •  

Вопрос

Если у меня есть код, как следующее:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

Будут ли исходные исключения брошены из обоих мест внутри нижней рамы METEERROR ()?

Это было полезно?

Решение

Формулировка в стандарте (§15.1 / 2) (упор мой):

Когда исключение брошено, управление передается на Ближайший обработчик с подходящим типом (15.3); «Ближайший» означает обработчик, для которого соединение-оператор, CTOR-инициализатор или функциональный корпус После этого ключевого слова попробуйте было недавно введено потоком управления и еще не вышла.

Когда есть блок попробовать «выйти»? Согласно грамматике (§15 / 1), попробуйте заканчиваться блоками последовательность обработчиков, поэтому блок заканчивается, когда последний обработчик заканчивается. Другими словами:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

Так что да, ваш код в порядке. При перебрешении ближайший блок TRY имеет соответствующий обработчик (а именно catch (...)), так что обработчик введен.

Другие советы

Ваш оригинальный код был в порядке. Вы поймали различные типы исключений и называли функцией, которая будет регистрировать сообщение и Rethrow. То throw Заявление не требуется, чтобы появиться непосредственно внутри соответствующего catch блокировать. Если вы называете одну из этих функций «Примечание», и вы нет В настоящее время обрабатывая исключение, хотя ваша программа позвонит terminate().

Ваш новый код тоже в порядке. Это нормально поймать все, а затем позвонить на другую функцию, которая образуется, чтобы перейти к более конкретному обработчику. Это то Диспетчер исключений IDIOM описана в FAQ C ++. Отказ Это выглядит немного своеобразным ритроу, исключением после Диспетчерский блок закончил, но если то же самое throw заявление произошло после noteError вернулся (внутри оригинала catch блок) вместо того, чтобы оно сейчас, то было бы совершенно обычным; Он продемонстрирован в стандарте, §15.1 / 6.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top