1

I have started learning default arguments and came across code like

void func(int, int = 4); //second parameter has default argument
func(5);                 //default argument will be used here as expected

As we can see when we call func in the above function call, we can omit the second argument and the compiler will still call the correct function as if we explicitly passed 4 as the second argument.


But when we call a function through a function pointer(as shown below), the default argument cannot be omitted. My question is why is there this restriction? I want to know the reason behind why the C++ standard does not allow to omit the second argument when we call the function using a function pointer.

void func(int, int = 4);
void (*ptr)(int, int) = func;
int main()
{
    ptr(5); //why does c++ disallow omitting the second argument here
}

I think the reason is most probably related to how a pointer can be used but I can't figure out by myself the exact reason as I'm a C++ beginner. Note also that I'm not looking for a solution to the above shown code but instead want to know the reason of why when calling a function through a function pointer, default arguments cannot be omitted.


Note

Note that I already know that C++ standard does not allow omitting the second argument when calling through pointer like ptr(5). I want to know the reasoning behind this restriction.

I also tried searching the web before asking this question but did not find similar question.

  • 2
    `void (*ptr)(int, int)` How exactly would the compiler or even a person know that there is a default for the second argument and what the default is? – tkausl May 28 '23 at 11:14
  • Simply put, because that's the way the language was defined. Default arguments are not part of the function's *type*, so they're not part of the function pointer. They're just syntactic sugar inserted by the compiler, and they only work when you call the function normally by name. If you're actually trying to ask for chapter and verse from the C++ language standard as a citation of this restriction, then you should [edit] your question to add the [[tag:language-lawyer]] tag (that would make it not a duplicate). – Cody Gray - on strike May 28 '23 at 11:15
  • Becuase the function pointer specification does NOT have any information on the default parameter. It is just a pointer to a generic function taking 2 int parameters. Note in C++ you might consider using std::function too (and yes no default arguments there too) – Pepijn Kramer May 28 '23 at 11:15
  • @CodyGray At the end of my question I have mentioned that I am not asking for the chapter or verse from the standard but the reasoning behind not allowing this. –  May 28 '23 at 11:16
  • How would that work? The default arguments belong to the function, not the function pointer. If you allowed default arguments on a function pointer, then what happens when you assign a function without default arguments to that function pointer, or with different default arguments. No doubt you could make up some rules to make it work, but is there any demand for this feature? – john May 28 '23 at 11:17
  • Default arguments are used at the callsite for the missing arguments. A function pointer is not allowed to have default arguments (if you tried, the compiler ought to have complained). – Eljay May 28 '23 at 11:17
  • @john You said that default argument belong to function. But I read that default argument are not part of function type. So how do they "belong" to function? –  May 28 '23 at 11:18
  • @Anya They are specified when you declare the function (but you are correct they are not part of the function type). – john May 28 '23 at 11:19
  • They are stitched into the callsite. They are not part of the function. They are a bit of a hack. They don't scale well for large projects (even moreso for shared frameworks), because changing the default arguments requires recompiling all the files that call the function that rely on the default arguments. – Eljay May 28 '23 at 11:21
  • 1
    `void func(int, int = 4)` does not declare two functions. It declares a single function that accepts two arguments of type `int`, which is why `void (*ptr)(int, int) ptr = func` works, but `void (*ptr1)(int) = func` will not. Default arguments are a syntactic hack, which [in your example] allows `func(2)` and `func(2,4)` to be equivalent, but only when calling `func()` directly by name (not via a pointer), and pointers to functions do not carry any information about default values of arguments. – Peter May 28 '23 at 11:38
  • You can try looking at the assembler code generated for functions and for their calls. You will find that a function expects all its arguments, getting them from registers and/or stack. Function call puts the arguments there. It is done at compile time. Now, default arguments can be also put there at compile time -- compiler, knowing which function is called, looks it up, finds default args, and put them in registers before call. The functions still has all the args! Pointer calls do the same, but they can't know where to look up for defaults. So the caller must provide all arguments. – Mike Tyukanov May 28 '23 at 12:49

0 Answers0