Подтвердить что ты не робот

Почему я могу назначить ссылку на функцию для анонимной переменной указателя функции?

Следующий код компилируется просто отлично, и я не уверен, почему. Может кто-нибудь объяснить мне, почему это законно?

Я использую 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;
}
4b9b3361

Ответ 1

Скорее всего, это связано с этой ошибкой, сообщенной Заком Вайнбергом:

Ошибка 68265 - произвольная синтаксическая бессмыслица, молча принятая после 'int (*) {}', пока следующая ближайшая скобка

(From Почему этот код недействительного кода успешно компилируется в g++ 6.0?:)

Компилятор С++ не может диагностировать плохо сформированные конструкции, такие как

  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 = С++ 98 вы получаете предупреждение: расширенный инициализатор списки доступны только с -std = С++ 11 или -std = gnu ++ 11 ", но с -std = С++ 11, а не peep.

Если какой-либо (или более) токенов int (*) {} 'удалены, вы делаете получить сообщение об ошибке. Кроме того, компилятор C не имеет такой же ошибки.

Конечно, если вы попробуете int (*) (int, int) {} или другие варианты, он ошибочно компилируется. Интересно, что разница между этим и предыдущими отчетами о дублировании/ошибках заключается в том, что int (*) (int, int) = asdf требует, чтобы asdf было именем в области видимости. Но я очень сомневаюсь, что ошибки различны по своей природе, поскольку основная проблема заключается в том, что GCC позволяет вам опустить идентификатор declarator.

[n4567 §7/​​8]: "Каждый init-declarator в списке init-declarator содержит ровно один идентификатор-декларатор, который является именем, объявленным что init-declarator и, следовательно, одно из имен, объявленных декларация".

Здесь странность:

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

В этом конкретном сценарии GCC не жалуется на обращение к адресу main (например, массивы, &main эквивалентно main).