通过价值获取例外 - gcc和clang不同意

时间:2016-03-23 02:34:29

标签: c++ gcc exception-handling clang language-lawyer

考虑这个简短的片段:

struct B {
    B() = default;
    explicit B(B const& ) { }
};

struct D : B { };

int main() {
    try {
        throw D{};
    }
    catch(B ) {
    }
}

gcc接受此代码,clang认为它格式不正确:

main.cpp:17:13: error: no matching constructor for initialization of 'B'
    catch(B ) {
            ^

谁是对的?

1 个答案:

答案 0 :(得分:4)

认为这是一个gcc错误(因为没有人对这个答案进行了评价,我将其提交为70375)。

两个编译器都正确地同意D{}应该被捕获,因为[except.handle]/3只检查BD的基类。

但处理程序的初始化在[except.handle]/15中定义为:

  

由异常声明声明的类型为 cv T cv T&的变量,是从异常对象初始化的,输入E,如下:
   - 如果TE的基类,则该变量从异常对象的相应基类子对象复制初始化(8.5);

这意味着初始化的工作原理如下:

D __temporary_object{};
B __handler = static_cast<B&>(__temporary_object);

这是不允许的,因为B的复制构造函数已标记为explicit(并且复制初始化只是没有删除它)。