【问题标题】:Why am I able to assign a function reference to an anonymous function pointer variable?为什么我可以将函数引用分配给匿名函数指针变量?
【发布时间】:2016-08-13 16:44:31
【问题描述】:

以下代码编译得很好,我不知道为什么。有人可以向我解释为什么这是合法的吗?

我正在使用g++ (Debian 6.1.1-10) 6.1.1 20160724 编译。

#include <iostream>

int sum(int x, int y) { return x + y; }

int main(int argc, char *argv[])
{
    using std::cout;

    int (*) (int, int) = &sum;
    cout << "what" << '\n';
}

附录

以下程序使用 g++ 5.4.0 版可以正常编译,但在 gcc 中编译失败。

int main()
{
    int (*) = 20;
}

【问题讨论】:

  • 这是一个无关紧要的细节。这是一个指针。它被分配给一个匿名函数指针。但是“int = 7;”不编译。 “int *=nullptr;”也没有。这里的某个地方可能有一个最令人烦恼的 parse 的表弟。
  • 这也编译了void foo(); ... int (*) (int, int) = &amp;foo; - 发生了一些奇怪的事情。 (g++ 5.1.0)
  • 算了。 int (*)(int, int); 也可以编译。
  • 请在问题中添加编译器信息。
  • 还有int (*) (int, int) = 5.3;(尽量避免衰减到右轴上的指针)

标签: c++ language-lawyer


【解决方案1】:

很可能与 Zack Weinberg 报告的this bug 有关:

错误 68265 - 在“int (*){}”之后静默接受任意语法废话,直到下一个右大括号

(来自Why does this invalid-looking code compile successfully on g++ 6.0? :)

C++ 编译器无法诊断格式错误的结构,例如

  int main()
  {
      int (*) {}
         any amount of syntactic nonsense
         on multiple lines, with *punctuation* and ++operators++ even...
         will be silently discarded
         until the next close brace
  }

使用 -pedantic -std=c++98 你会得到“警告:扩展初始化程序 列表仅适用于 -std=c++11 或 -std=gnu++11",但 -std=c++11,不是偷看。

如果任何一个(或多个)标记 'int ( * ) { }' 被删除,你可以 得到一个错误。此外,C 编译器没有相同的错误。

当然,如果您尝试int (*) (int, int) {} 或其他变体,它会错误地编译。有趣的是,这与之前的重复/错误报告之间的区别在于 int (*) (int, int) = asdf 要求 asdf 是范围内的名称。但我非常怀疑这些错误本质上是不同的,因为核心问题是 GCC 允许您省略 declarator-id

[n4567 §7/8]:“init-declarator-list 中的每个 init-declarator 只包含一个 declarator-id,它是由 init-declarator 并因此是由 声明。”

这里有一个奇怪的地方:

int (*) (int, int) = main;

在这种特定场景下,GCC 不会抱怨取 main 的地址(像数组,&amp;main 等价于 main)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多