I was looking into most vexing parse, and I stumbled upon something like this:
Foo bar(Baz()); // bar is a function that takes a pointer to a function that returns a Baz and returns a Foo
This is quite different from the typical syntax of return-type(*name)(parameters)
. Are the parenthesis present the parenthesis for the parameter list, or are they for the name?
Function Pointer Syntaxvoid (*foo)( int ); In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function.
A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing a data value, a function pointer points to executable code within memory.
1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function's name can also be used to get functions' address.
Fully explicit form:
Foo bar(Baz f());
bar
is a function that takes a single parameter f
, which is a function (taking no arguments) returning Baz
.
Without naming the parameter:
Foo bar(Baz ());
The reason bar
ends up taking a pointer to a function is that functions cannot be passed by value, so declaring a parameter as a function automatically decays it into a pointer. The above declaration is equivalent to:
Foo bar(Baz (*)());
// or:
Foo bar(Baz (*f)()); // with a named parameter
This is similar to void foo(int [10])
where int [10]
also means int *
in a parameter list.
There are two sets of parentheses in the declaration. The outer set of parentheses are the parameter list of the function bar
:
Foo bar(Baz());
^ ^
Baz()
in this declaration is a function type. The parentheses in a function type declaration delimit the parameter list of that function.
Foo bar(Baz());
^^
To clarify: In the context of a function parameter declarator, a function type is adjusted to be a pointer to a function of that type. So the declaration is in fact equivalent to:
Foo bar(Baz(*)());
^ ^
The highlighted parentheses of this alternative pointer argument declarator are not present in the "pre-adjustement" declaration.
Relevant standard rule:
[dcl.fct]
The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. ...
Are the parenthesis present the parenthesis for the parameter list, or are they for the name?
They are for the parameter list.
So:
Foo bar(Baz());
declares a function which accepts a single parameter of a type function which returns Baz
and accepts no parameters.
This, in turns, equal to a a function declaration which accepts a single parameter of a type pointer to a function which returns Baz
and accepts no parameters. as (from function):
The type of each function parameter in the parameter list is determined according to the following rules:
...
3) If the type is a function type F, it is replaced by the type "pointer to F"
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With