为什么我能够为匿名函数指针变量分配函数引用?

fie*_*omp 20 c++ language-lawyer

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

我正在使用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';
}
Run Code Online (Sandbox Code Playgroud)

附录

以下程序使用g ++版本5.4.0进行编译,但无法在gcc中编译.

int main()
{
    int (*) = 20;
}
Run Code Online (Sandbox Code Playgroud)

uh *_*per 11

这很可能与Zack Weinberg报告的这个错误有关:

错误68265 - 在'int(*){}'之后默默接受任意语法废话直到下一个紧密支撑

(来自为什么这个看起来无效的代码在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
  }
Run Code Online (Sandbox Code Playgroud)

使用-pedantic -std = c ++ 98,您会收到"警告:扩展初始化列表仅适用于-std = c ++ 11或-std = gnu ++ 11",但使用-std = c ++ 11,而不是偷看.

如果删除了任何一个(或多个)标记'int(*){}',则会出现错误.此外,C编译器没有相同的错误.

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

[n4567§7/ 8]:"每个初始化声明符初始化说明符列表 中只包含一个声明符-ID,这是由该声明的名称初始化说明符,因此在声明中声明的名字之一."

这是一个奇怪的事:

int (*) (int, int) = main;
Run Code Online (Sandbox Code Playgroud)

在这个特定的场景中,GCC不会抱怨获取main的地址(比如数组,&main相当于main).