按值捕获异常 - gcc 和 clang 不同意
Catching an exception by value - gcc and clang disagree
考虑这个简短的片段:
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)。
两个编译器都正确地同意应该按照 [except.handle]/3 捕获D{}
,它只检查B
是 D
的基类。
但是处理程序的初始化在 [except.handle]/15 中定义为:
由异常声明声明的 cv
T
或 cvT&
类型的变量从E
类型的异常对象初始化,如下所示:
— 如果T
是E
的基类,则变量从异常对象的相应基类子对象复制初始化 (8.5);
这意味着初始化的工作方式为:
D __temporary_object{};
B __handler = static_cast<B&>(__temporary_object);
这应该是不允许的,因为B
的复制构造函数被标记为explicit
(并且复制初始化只是不会削减它)。
相关文章:
- 为什么 Clang 不允许"and"作为函数名称?
- decltype(1, t) 应该是 l 值引用吗?(编译器不同意)
- 为什么 Clang 不喜欢__DATE__宏?
- GCC/CLang不同意模板模板参数的部分特化
- 编译包含指向模板函数的指针的初始值设定项列表时,gcc 出错,但 clang 不出错
- Clang不会编译GCC会编译的模板专业化
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- 为什么 CLang++ 不优化循环,而 G++ 优化循环?
- 为什么Clang不喜欢boost::transform_iterator?
- 除了说明符神秘地破坏编译(Clang,GCC不同意)
- 为什么 clang 不允许通过实例访问嵌套枚举类?
- C++函数到指针的隐式转换:哪个编译器是正确的?Clang和GCC不同意
- Clang和Gcc不同意实例化后的显式专业化
- clang vs g 在类模板上不同意参数和模板模板参数重新分支
- 从支撑的std::string构造std::string_view,clang和gcc不同意-Wconversion
- constexpr 表达式和变量生存期,G++ 和 Clang 不同意的一个例子
- 按值捕获异常 - gcc 和 clang 不同意
- 当函数模板专门化到不同的命名空间时,GCC和clang不同意
- 当显式模板实例化定义在显式声明之前时,GCC和clang不同意
- std::make_shared是否执行值初始化(GCC和clang不同意)