fierce_comp fierce_comp - 3 months ago 8
C++ Question

Why am I able to assign a function reference to an anonymous function pointer variable?

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

Answer

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).

Comments