c++ - break/continue/return 应该被异常打断吗?

标签 c++ language-lawyer

我在使用我的语言时遇到了一个有趣的流程控制场景。如果在处理 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/

相关文章:

c++ - 如何复制 CString 功能

c++ - 生成给定集合的子集(使用递归)的程序的执行涉及哪些步骤?

c++ - 以下内容是否确实违反了 ODR?

java - 调用 JNI 函数创建对象

C++ 获取 unordered_set *没有*序列化的字节表示

c++ - 在 C++ 中对 vector 使用函数

具有继承模板的C++调用函数

c++ - MSVC 中的折叠表达式

c++ - 为什么 SFINAE 在更改类模板特化的位置时会搞砸?这是 C++ 错误吗?

c++ - 对参数依赖查找和友元函数定义的混淆