Я столкнулся с интересным сценарием с контролем потока во время работы на моем языке. Что произойдет, если при обработке инструкции break
возникает исключение. Кажется, что GCC полагает, что поток прерывается, но стандарт кажется несколько молчащим о том, что должно произойти.Должно ли прерывание/продолжение/возвращение прерываться за счет исключения?
Например, что должна делать следующая программа?
#include <iostream>
using namespace std;
struct maybe_fail {
bool fail;
~maybe_fail() {
if(fail)
throw 1;
}
};
int main() {
for(int i=0; i < 6; ++i) {
cout << "Loop: " << i << endl;
try {
maybe_fail mf;
mf.fail = i % 2;
if(i == 3)
break;
} catch(int) {
cout << "Caught" << endl;
}
}
return 0;
}
Обратите внимание, что return
также будет заблокирован, как будет continue
(добавить выход после улова, чтобы увидеть, что). Попадание на goto
за пределами блока также будет поймано.
Каков правильный поток? Стандарт, похоже, не затрагивает этого: раздел 6.6 о инструкциях перехода не упоминает, также раздел 15 об обработке исключений. Я понимаю, что исключения в деструкторах в ужасно плохом виде, но если вы используете что-то вроде BOOST_SCOPE_EXIT для заявлений о задержке, это поведение может стать весьма важным.
Возможно, интересный, тот же поток происходит в Java и Python, поэтому, по крайней мере, на императивных языках существует определенная последовательность.
Ваш вопрос, кажется, подтверждает совет в FAQ на C++: http://www.parashift.com/c++-faq-lite/dtors-shouldnt-throw.html В принципе, не бросайте исключения в деструкторы. Этот вопрос в FAQ часто указывал, как вызывается 'terminate()', если вы находитесь в ситуации с «двойным исключением», но ваш пример, похоже, продолжает давать советы, что это просто плохо. –
@Kevin, абсолютно, этот совет будет распространяться на любой оператор «defer» на любом языке (включая BOOST_SCOPE_EXIT для C++). –
как еще вы могли бы интерпретировать поведение? выбросить исключение в деструктор, а потом что? – bdwain