应该中断/继续/返回是否会被异常中断?

时间:2013-04-19 04:01:03

标签: c++ language-lawyer

我在使用语言时遇到了流量控制的有趣场景。如果在处理break语句时抛出异常会发生什么。海湾合作委员会似乎相信破裂流程已经失去,但标准似乎对应该发生的事情保持沉默。

例如,以下程序实际应该做什么?

#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之后添加输出以查看)。 也会抓住在区块之外尝试goto

什么是正确的流量?标准似乎没有解决这个问题:关于跳转语句的第6.6节没有提及,关于异常处理的第15节也没有提到。我确实理解析构函数中的异常形式非常糟糕,但如果你使用类似BOOST_SCOPE_EXIT的东西来推迟语句,这种行为可能会变得非常重要。

也许有趣的是,同样的流程发生在Java和Python中,所以至少在命令式语言中似乎有一些一致性。

2 个答案:

答案 0 :(得分:4)

15.1抛出异常:

  

2抛出异常时,控制权转移到匹配类型最近的处理程序(15.3);   “nearest”表示遵循try关键字的复合语句或ctor-initializer的处理程序   最近由控制线输入,但尚未退出。

一旦控制转移到异常处理程序,它就会从那里继续。没有机制可以“记住”代码位于break的中间,然后在处理异常后以某种方式恢复代码。

答案 1 :(得分:0)

根据标准中的具体措辞,我会说这是模棱两可的。该文本不足以确定这些情况的预期流量。由于编写器的编写方式,我们现在的惯例很可能只是偶然的。

请参阅我的博客主题How to catch a "return" statement