【问题标题】:Is there anything wrong with gcc when compiling a nonthrowing pointing to a function which might throw?编译指向可能抛出的函数的非抛出时 gcc 有什么问题吗?
【发布时间】:2018-04-07 08:59:48
【问题描述】:

我已阅读《C++ Primer 5th ed》一书。在 Exception Specifications and Pointers、Virtuals 和 Copy Control 部分中,它说:

也就是说,如果我们声明一个具有非抛出异常规范的指针,我们可以只使用该指针指向类似限定的 职能。

而且我也参考noexcept specifier (since C++11),也有类似的:

指向非抛出函数的指针可隐式转换(C++17 起)可以分配(C++17 前)指向潜在抛出函数的指针,但反之则不行。

void ft(); // potentially-throwing
void (*fn)() noexcept = ft; // error

当我使用gcc version 5.4.0 20160609 编译示例 sn-p 时,没有错误或警告。
但是当我用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 编译器有什么问题吗?

【问题讨论】:

    标签: c++ c++11 gcc visual-c++ noexcept


    【解决方案1】:

    GCC 错误。这也不是有效的 C++11/14。 N3337[except.spec]/5,强调我的:

    如果一个虚函数有一个异常规范,所有 任何覆盖的函数的声明,包括定义 任何派生类中的虚函数只允许异常 基类的异常规范所允许的 虚函数。 [ 例子: ... —结束例子 ] 类似的 限制适用于指针的赋值和初始化 函数、指向成员函数的指针和对函数的引用: 目标实体应至少允许其允许的例外情况 赋值或初始化中的源值。

    这就是人们说 C++17 之前的异常规范是“影子类型系统”时的意思:它们不是实际类型的一部分,而是在多个上下文中表现(初始化、赋值、虚拟覆盖)好像他们是一样。

    【讨论】:

      【解决方案2】:

      根据this page,C++17 特性“使异常规范成为类型系统的一部分”从 GCC 7.0 开始可用。

      【讨论】:

      • 严格来说,这并不能回答问题。 OP 的代码是无效的 C++11(有关详细信息,请参阅下面的 T.C 的回答)。这是一个 GCC 错误。
      • @zhenguoli 有人指出我的回答是错误的。你应该接受 T.C. 的回答,这样我就可以删除这个
      【解决方案3】:

      历史上,exception specifiers have not been part of the type system:

      1. 异常规范应该是类型系统的一部分吗?

      […]

      EWG 决定不应对此问题采取任何行动。

      这当然有点令人惊讶。这不是类型系统本身的漏洞,因为仍然在运行时检查类型(如果需要会导致异常翻译)。

      不过,这个问题在P0012R1 中复活,并与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 中。通常,在编译器实现新的语言特性之前会有一些延迟。

      【讨论】:

        猜你喜欢
        • 2021-06-08
        • 2020-08-22
        • 2015-05-25
        • 2022-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-16
        相关资源
        最近更新 更多