c++ - 按值捕获异常 - gcc 和 clang 不同意

标签 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 ) {
            ^

谁是对的?

最佳答案

认为这是一个 gcc 错误(由于还没有人否决这个答案,我将其提交为 70375)。

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

但是handler的初始化定义在[except.handle]/15中作为:

The variable declared by the exception-declaration, of type cv T or cv T&, is initialized from the exception object, of type E, as follows:
— if T is a base class of E, the variable is copy-initialized (8.5) from the corresponding base class subobject of the exception object;

这意味着初始化工作为:

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

这应该是不允许的,因为 B 的复制构造函数被标记为 explicit(并且复制初始化不会削减它)。

关于c++ - 按值捕获异常 - gcc 和 clang 不同意,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36168799/

相关文章:

c++ - 如何将函数存储在类的成员中? (使用函数作为回调)

c++ - 如何在C++中跳到Ofstream对象的下一行

c - gcc 将自动调整结构大小

c - 初学者 C 难题 : why doesn't 25 == 25?

c++ - APR(Apache可移植运行时)1.2.2 RegEx?

c++ - Eclipse 报错 127

c++ - 对静态成员的 undefined reference

Java 捕获异常和子类

c# - Debug.Assert 与特定抛出的异常

database - 在 Spring Security 中处理 DataAccessException