Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function that returns a function pointer syntax

I'm having trouble with the following syntax in C:

float (*func(unsigned id))(float value) {
    ...
}

I understand that:

  • It is a definition of a function called func
  • func accepts one argument of type unsigned called id
  • func returns a pointer to a function that looks like: float f(float value)

But I don't understand why the return value of f (the returned function pointer) is separated from its argument list.

Also, is: func(unsigned id) an expression that evaluates to some pointer? Is this the reason why (*func(unsigned id)) works?

Can someone clarify this syntax step by step?

like image 728
Alon Gubkin Avatar asked Sep 04 '14 17:09

Alon Gubkin


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.

Can a function return a pointer value?

We can pass pointers to the function as well as return pointer from a function. But it is not recommended to return the address of a local variable outside the function as it goes out of scope after function returns.

How do you call a function pointer in C++?

To pass the value by pointer, argument pointers are passed to the functions just like any other value. So accordingly you need to declare the function parameters as pointer types as in the following function swap(), which exchanges the values of the two integer variables pointed to by its arguments.

Can you return a pointer in C++?

We can retrieve a pointer to the first character in the sequence using the data() built-in function and pass after the return statement. Finally, we can operate on the char array using the returned pointer as needed.


1 Answers

The expression func(id) returns a pointer to a function that takes a float as argument and returns a float.

float(*f)(float v);  // pointer to a function 
float val;     

f = func(3);       // returns a pointer to a function 
val = (*f)(3.14);  // calls the function pointed to with argument 3.14

Of course, you could rewrite the last statement:

val = (*func(3))(3.14);  // take the ptr returned by func(3) and call the function pointed to. 

If you have a function like:

float fct1 (float v) { return 2.0f*v+3.1f; }  

you could write:

f = fct1;       // reassign the pointer to function f to the adress of fct1

Let's look at the syntax. The C11 standard (draft N1570) states in 6.5.2.2 point 1: that "The expression that denotes the called function) shall have type pointer to function" and in point 3 that: "A postfix expression followed by parentheses () containing a possibly empty, comma-separated list of expressions is a function call."

This covers of course the usual cases:

 val = fct1 (3.14);   // fct1 is the function designator which adresses the function  
 val = (*f) (3.14);  // (*f) the dereferenced function pointer, so it addresses the function

But the following is also valid according to standard:

 val  = f(3.14);    //  This works as well, because f is a pointer to a function
 val = func(3)(3.14)  // works also because func(3) is a pointer to a function

However first expression is ambiguous for the human reader, who might think of f as a function designator, expecting it to be defined somewhere. And the second is unusual as well. Furthermore, earlier versions of C didn't recognize them. My K&R edition for 1978 required the form (*f)() to call a function pointer.

A last syntactic remark: If you would define f as float *f (float); it wouldn't be understood as a pointer to a function, but as a forward declaration of a plain function called f and returning a pointer to float. Why ? Because the C precedence rules give () a higer precedence than * meaning that the compiler would understand it as (float *)(f(float)). This is why an explicit parenthesis is required to show that (*f) is the function pointer.

like image 196
Christophe Avatar answered Sep 18 '22 01:09

Christophe