20

The following code compiles just fine and I'm not sure why. Can someone please explain to me why this is legal?

I am using g++ (Debian 6.1.1-10) 6.1.1 20160724 to compile.

#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';
}

Addendum

The following program compiles fine using g++ version 5.4.0 but fails to compile in gcc.

int main()
{
    int (*) = 20;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
fierce_comp
  • 203
  • 1
  • 6
  • That's an irrelevant detail. It's a pointer. It's being assigned to an anonymous function pointer. But "int = 7;" doesn't compile. Neither does "int *=nullptr;". There's probably a most vexing parse's cousin, somewhere in here. – Sam Varshavchik Aug 13 '16 at 16:49
  • 1
    This also compiles `void foo();` ... `int (*) (int, int) = &foo;` - something strange is going on. (g++ 5.1.0) – Richard Critten Aug 13 '16 at 16:49
  • 1
    Forget that. `int (*)(int, int);` also compiles. – Sam Varshavchik Aug 13 '16 at 16:52
  • 1
    Please add compiler info to the question. – R Sahu Aug 13 '16 at 16:53
  • 3
    And also `int (*) (int, int) = 5.3;` (trying to avoid decay to pointer on the rhs) – Richard Critten Aug 13 '16 at 16:55
  • I am able to compile `int a; int (*) = &a;` using g++ 5.4.0. Strange indeed. – R Sahu Aug 13 '16 at 16:55
  • It compiles under g++ 4.9.2 as well. – Todd Knarr Aug 13 '16 at 17:00
  • http://stackoverflow.com/questions/10405436/anonymous-functions-using-gcc-statement-expressions The syntax is a GCC extension, not standard C. – Todd Knarr Aug 13 '16 at 17:00
  • @ToddKnarr That question is about C, not C++. This applies only to C++. Trying to compile `int (*)(int, int);`: It compiles even with `g++ -Wall -Wextra -pedantic -std=c++98 anon.c`. Trying to compile it with gcc yields "error: expected identifier or ‘(’ before ‘)’ (gcc 5.3.1) – Jonathon Reinhart Aug 13 '16 at 17:02
  • Possible duplicate of [Why does this invalid-looking code compile successfully on g++ 6.0?](http://stackoverflow.com/questions/33614455/why-does-this-invalid-looking-code-compile-successfully-on-g-6-0) – uh oh somebody needs a pupper Aug 13 '16 at 17:31

1 Answers1

11

It's very likely to be related to this bug reported by Zack Weinberg:

Bug 68265 - Arbitrary syntactic nonsense silently accepted after 'int (*){}' until the next close brace

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

The C++ compiler fails to diagnose ill-formed constructs such as

  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
  }

With -pedantic -std=c++98 you do get "warning: extended initializer lists only available with -std=c++11 or -std=gnu++11", but with -std=c++11, not a peep.

If any one (or more) of the tokens 'int ( * ) { }' are removed, you do get an error. Also, the C compiler does not have the same bug.

Of course, if you try int (*) (int, int) {} or other variants, it erroneously compiles. The interesting thing is that the difference between this and the previous duplicate/bug reports is that int (*) (int, int) = asdf requires asdf to be a name in scope. But I highly doubt that the bugs are different in nature, since the core issue is that GCC is allowing you to omit a declarator-id.

[n4567 §7/8]: "Each init-declarator in the init-declarator-list contains exactly one declarator-id, which is the name declared by that init-declarator and hence one of the names declared by the declaration."

Here's an oddity:

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

In this specific scenario, GCC doesn't complain about taking the address of main (like arrays, &main is equivalent to main).