当编译指向可能抛出的函数的非throwing时,gcc有什么问题吗
Is there anything wrong with gcc when compiling a nonthrowing pointing to a function which might throw?
我读过C++初级读本第五版。在异常规范和指针、虚拟和复制控制一节中,它说:
也就是说,如果我们声明一个具有非throwing异常规范的指针,我们只能使用该指针指向类似的限定功能。
我也提到了noexcept说明符(由于C++11),还有类似的东西:
指向非抛出函数的指针是隐式可转换的(因为C++17),可以分配(直到C++17)给指向潜在抛出函数的指示器,但不能反过来。
void ft(); // potentially-throwing
void (*fn)() noexcept = ft; // error
当我使用gcc version 5.4.0 20160609
编译示例代码段时,没有任何错误或警告
但是当我用Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
编译它时,它抱怨error C2440: 'initializing': cannot convert from 'void (__cdecl *)(void)' to 'void (__cdecl *)(void) noexcept'
。这似乎是正确的行为。
所以我想知道gcc
编译器有什么问题吗?
GCC错误。这也不是有效的C++11/14。N3337[除.spec]/5外,强调矿:
如果虚拟函数有异常规范,则所有重写的任何函数的声明,包括定义任何派生类中的虚拟函数只能允许异常基类的异常规范允许的虚拟功能。[示例:…--结束示例]类似限制适用于指针的分配和初始化函数、指向成员函数的指针以及对函数的引用:目标实体应至少允许赋值或初始化中的源值
当人们说C++17之前的异常规范是一个"影子类型系统"时,这就是他们的意思:它们不是实际类型的一部分,而是在几个上下文(初始化、赋值、虚拟重写)中表现得像是。
根据此页面,C++17功能"将异常规范作为类型系统的一部分"从GCC 7.0开始提供。
历史上,异常说明符不是类型系统的一部分:
- 异常规范是否应该是类型系统的一部分
[…]
EWG决定不应就此问题采取任何行动。
这当然有点令人惊讶。这并不是类型系统中的漏洞,因为在运行时仍会检查类型(如有必要,会导致异常翻译)。
然而,这个问题在P0012R1中重新出现,并通过以下提交合并到标准中:
commit 6e75f2d588a4b1b0c220eb8eec4b9ad8cb6107f3
Author: Dawn Perchik <dperchik@embarcadero.com>
Date: Thu Oct 29 12:11:02 2015 -0700
P0012R1 Make exception specifications be part of the type system, version 5
所以它不是在C++14中,而是在C++17中。通常,在编译器实现新的语言功能之前会有一些延迟。
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 奇怪的结构&GCC&clang(void*返回类型)
- GCC本机矩阵运算库
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- gcc和c++17的过载解析失败
- 数据成员SFINAE的C++17测试:gcc vs clang
- GCC对可能有效的代码抛出init list生存期警告
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 使用gcc从静态链接的文件中查找可选符号
- 普通环路未使用gcc 4.8.5自动矢量化
- 有了gcc,是否可以链接库,但前提是它存在
- 在clang++预处理器中确定gcc工具链版本
- 为什么 gcc 编译这个而 msvc 没有
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 如何使用Clang/GCC在Mac上为C/C++设置VSCode
- 当编译指向可能抛出的函数的非throwing时,gcc有什么问题吗