20

Following code can't be compiled with g++ version 5.4.0 with option -std=c++1y:

void f(int=0) ;

int main() {
    f(); // ok
    (*f)(2);// ok
    (*f)();// ok c++11; error with c++14: too few arguments to function
    return 0;
}

The function declared to have default argument, so what is wrong here? thanks for help.

And why does g++ -c -std=c++11 compile?

max66
  • 65,235
  • 10
  • 71
  • 111
  • 1
    The obvious answer is to try a newer `g++` version. The 5 line is old, and 5.4 isn't even its newest minor release. It's also prudent to search the GCC Bugzilla in cases like this, as the issue is probably already known, but filtering through to older versions can take a while and sometimes just doesn't happen. – underscore_d Oct 30 '17 at 11:22
  • Seems like a compiler bug. Clang rejects this code both as C++11 and C++14. – StoryTeller - Unslander Monica Oct 30 '17 at 11:25
  • Could this be related to the order of optimisation passes? i.e. the function pointer optimised to a direct call before the arguments are processed – underscore_d Oct 30 '17 at 11:32

2 Answers2

25

Accepting (*f)() as valid is a GCC bug. The letter of the standard indicates that using a function name with unary * should cause the function name to decay into a pointer. The pointer should then be dereferenced to obtain the functions address for the call expression.

But GCC seems clever, and omits the above behavior. It treats (*f) simply as f. And calling f can be done with default arguments.

However, one can force GCC to preform the decay. Unary + applied on the function name will decay it to a pointer forcefully. So the following two:

(+f)();
(*+f)();

Cause GCC to emit error: too few arguments to function on either standard revision, in both GCC 7.2 and GCC 6.3.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
8

Default arguments are not a part of function type, so they are discarded when you implicitly convert function to function pointer and then indirect that pointer.

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79