Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax of an un-named function pointer in C++

Tags:

c++

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?

like image 498
Krystian S Avatar asked Sep 30 '18 20:09

Krystian S


People also ask

What is the syntax of function pointer?

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.

What is the name for function pointer?

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.

What is function pointer in C with example?

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.


3 Answers

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.

like image 99
melpomene Avatar answered Oct 19 '22 21:10

melpomene


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

like image 31
eerorika Avatar answered Oct 19 '22 21:10

eerorika


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"

...

like image 3
Edgar Rokjān Avatar answered Oct 19 '22 20:10

Edgar Rokjān