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

时间:2016-08-13 16:44:32

标签: 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';
}

附录

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

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

1 个答案:

答案 0 :(得分:11)

这很可能与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的地址(如数组,&main等同于main)。