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

C++ 为什么我能够将函数引用分配给匿名函数指针变量?,c++,language-lawyer,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

下面的代码编译得很好,我不知道为什么。有人能给我解释一下为什么这是合法的吗

我正在使用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';
}

这很可能与Zack Weinberg的报道有关:

Bug 68265-在“int(*){}”之后,直到下一个右大括号之前,任意的语法废话都会被默默地接受 (发件人:)

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
作为范围内的名称。但我高度怀疑这些bug在本质上是不同的,因为核心问题是GCC允许您省略声明器id

[n4567§7/8]:“初始声明人列表中的每个初始声明人 仅包含一个声明器id,该id是由声明的名称 该init声明符,因此是 声明。”

这里有一个奇怪的现象:

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

在这个特定场景中,GCC不会抱怨获取main的地址(就像数组一样,
&main
相当于
main
)。

这是一个不相关的细节。这是一个指针。它被分配给一个匿名函数指针。但是“int=7;”不能编译。“int*=nullptr;”也不适用。在这里的某个地方,可能有一个最烦人的parse的表亲<代码>整数(*)(整数,整数)=&foo-发生了一些奇怪的事情。(g++5.1.0)忘记这一点<代码>整数(*)(整数,整数)也编译。请在问题中添加编译器信息。还有
int(*)(int,int)=5.3(试图避免衰减到rhs上的指针)
int (*) (int, int) = main;