在编译指向可能抛出的函数的非抛出指向时,gcc 有什么问题吗?
Is there anything wrong with gcc when compiling a nonthrowing pointing to a function which might throw?
我已经阅读了《C++ Primer》第 5 版这本书。在异常规范和指针、虚拟和复制控制部分,它说:
That is, if we declare a pointer that has a nonthrowing exception specification, we can use that pointer only to point to similarly qualified
functions.
我也参考了noexcept specifier (since C++11),还有类似的:
Pointers to non-throwing functions are implicitly convertible (since C++17)can be assigned (until C++17) to pointers to potentially-throwing functions, but not the other way around.
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
编译器有什么问题吗?
根据 this page,C++17 功能 "Make exception specifications be part of the type system" 从 GCC 7.0 开始可用。
历史上,exception specifiers have not been part of the type system:
- Should exception-specifications be part of the type system?
[…]
EWG determined that no action should be taken on this issue.
这确实有点令人惊讶。这不是类型系统中的漏洞,因为类型仍然在 运行 时间检查(必要时导致异常翻译)。
但是,这个问题在 P0012R1 and merged into the standard with this commit 中再次出现:
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 中。通常,在编译器实现新的语言功能之前会有一些滞后。
海湾合作委员会错误。这也不是有效的 C++11/14。 N3337 [except.spec]/5,强调我的:
If a virtual function has an exception-specification, all
declarations, including the definition, of any function that overrides
that virtual function in any derived class shall only allow exceptions
that are allowed by the exception-specification of the base class
virtual function. [ Example: ... — end example ] A similar
restriction applies to assignment to and initialization of pointers to
functions, pointers to member functions, and references to functions:
the target entity shall allow at least the exceptions allowed by the
source value in the assignment or initialization.
这就是人们说 C++17 之前的异常规范是 "shadow type system" 的意思:它们不是实际类型的一部分,但在多个上下文中表现(初始化、赋值、虚拟覆盖)就好像它们一样。
我已经阅读了《C++ Primer》第 5 版这本书。在异常规范和指针、虚拟和复制控制部分,它说:
That is, if we declare a pointer that has a nonthrowing exception specification, we can use that pointer only to point to similarly qualified functions.
我也参考了noexcept specifier (since C++11),还有类似的:
Pointers to non-throwing functions are implicitly convertible (since C++17)can be assigned (until C++17) to pointers to potentially-throwing functions, but not the other way around.
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
编译器有什么问题吗?
根据 this page,C++17 功能 "Make exception specifications be part of the type system" 从 GCC 7.0 开始可用。
历史上,exception specifiers have not been part of the type system:
- Should exception-specifications be part of the type system?
[…]
EWG determined that no action should be taken on this issue.
这确实有点令人惊讶。这不是类型系统中的漏洞,因为类型仍然在 运行 时间检查(必要时导致异常翻译)。
但是,这个问题在 P0012R1 and merged into the standard with this commit 中再次出现:
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 中。通常,在编译器实现新的语言功能之前会有一些滞后。
海湾合作委员会错误。这也不是有效的 C++11/14。 N3337 [except.spec]/5,强调我的:
If a virtual function has an exception-specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception-specification of the base class virtual function. [ Example: ... — end example ] A similar restriction applies to assignment to and initialization of pointers to functions, pointers to member functions, and references to functions: the target entity shall allow at least the exceptions allowed by the source value in the assignment or initialization.
这就是人们说 C++17 之前的异常规范是 "shadow type system" 的意思:它们不是实际类型的一部分,但在多个上下文中表现(初始化、赋值、虚拟覆盖)就好像它们一样。