【问题标题】:using vs typedef pointer-to-noexcept-function inconsistency使用 vs typedef 指向 noexcept 函数的指针不一致
【发布时间】:2023-03-22 10:06:01
【问题描述】:

我意识到我可以通过using 为指向noexcept 函数的指针声明一个类型,但是如果我使用typedef,则禁止这样的声明。考虑下面的代码:

#include <iostream>

using fptr = void(*)() noexcept;
// typedef void(*FPTR)() noexcept; // fails to compile

void f() noexcept
{
    std::cout << "void f() noexcept" << std::endl;
}

void g()
{
    std::cout << "void g()" << std::endl;
    throw 10;
}

int main()
{
    fptr f1 = f;
    fptr f2 = g; // why can we do this?

    try {
        f1();
        f2();
    }
    catch (...)
    {
        std::cout << "Exception caught" << std::endl;
    }
}

如果我取消注释 FPTR 声明,我会得到 ​​p>

error: 'FPTR' declared with an exception specification

但是,using 工作正常。使用 gcc4.9 和 gcc5 编译。

我的问题是:

  1. 为什么会出现这种不一致?
  2. 为什么我们甚至可以使用usingnoexcept,因为我们可以将指针绑定到未声明noexcept 的函数,如fptr f2 = g;

好像是gcc相关的bug,连gcc5都没有捕捉到。填写错误报告

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65382

【问题讨论】:

  • “我意识到我可以通过 using 声明一个指向 noexcept 函数的指针” 不,你不能。那是一种类型,而不是指针。
  • @LightnessRacesinOrbit 是的,你是对的,这就是我的意思,更正它

标签: c++ exception c++11


【解决方案1】:

这似乎是 GCC 中的一个错误; Clang 拒绝两者,因为类型别名或typedefs 中不允许异常规范。这可以在以下位置找到:

15.4 异常规范 [except.spec]

2异常规范只能出现在函数类型、函数类型指针、函数类型引用或成员函数类型指针的函数声明符上那是声明或定义的顶级类型,或者在函数声明器中作为参数或返回类型出现的这种类型。 异常规范不得出现在 typedef 声明或 别名声明中。

[...]

该标准还明确规定两者应保持一致:

7.1.3 typedef 说明符 [dcl.typedef]

2typedef-name 也可以由 alias-declaration 引入。 using 关键字后面的标识符成为 typedef-name 并且标识符后面的可选 attribute-specifier-seq 属于该 typedef-name它与typedef 说明符引入的语义相同。特别是,它没有定义一个新的类型并且它不会出现在 type-id 中。

(强调我的)

回答您的第二个问题:GCC 可能只是忽略了异常规范,因为函数不能仅在异常规范上重载——它不是函数签名的一部分。可以在这里找到:

8.3.5 函数[dcl.fct]

6 [...] 返回类型、参数类型列表、ref-qualifiercv-qualifier-seq,但不是默认参数 (8.3.6) 或异常规范 (15.4),是函数类型的一部分。 [ 注意: 在函数指针、函数引用和成员函数指针的赋值和初始化过程中会检查函数类型。 — 尾注 ]

【讨论】:

  • 我为 gcc5 填写了一个错误,因为我无法在 bugzilla 中找到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 2011-03-04
  • 1970-01-01
  • 2016-06-03
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多