我在使用我的语言时遇到了一个有趣的流程控制场景。如果在处理 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
也会被阻止(在 catch 之后添加输出以查看)。尝试在 block 外 goto
也会被捕获。
什么是正确的流程?该标准似乎没有解决这个问题:关于跳转语句的第 6.6 节没有提及,关于异常处理的第 15 节也没有提及。我确实理解析构函数中的异常是非常糟糕的形式,但是如果您对 defer 语句使用 BOOST_SCOPE_EXIT 之类的东西,这种行为可能会变得非常重要。
也许有趣的是,相同的流程发生在 Java 和 Python 中,因此至少在命令式语言中似乎存在一些一致性。
最佳答案
这在 15.1 抛出异常中有介绍:
2 When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3); “nearest” means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited.
一旦控制权转移到异常处理程序,它就从那里继续。没有机制可以“记住”代码处于 break
的中间,然后在处理异常后以某种方式恢复它。
关于c++ - break/continue/return 应该被异常打断吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16096978/