Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Ways To Pass Function As Argument To Function

I've notices that there seem to be different ways to pass a function as a parameter to another function. The prototypes are:

void foo1(double f(double));

and

void foo2(double (*f)(double));

Is there a difference between the two? Are they implemented in the same way? Are there any other ways to pass functions?

like image 858
Jean-Luc Avatar asked Dec 25 '22 21:12

Jean-Luc


1 Answers

The second is arguably the 'proper' way to write it. It says that the argument to foo1() is a pointer to a function. The first says that the argument is a function, but you can't pass functions as functions per se, so the compiler treats it as a pointer to function. So, in practice, they are equivalent — in this context. But, in other contexts, you would not be able to use the double f(double); notation to declare a pointer to function.

ISO/IEC 9899:2011 §6.7.6.3 Function declarators (including prototypes)

¶8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type", as in 6.3.2.1.

Subsidiary question and answer

Could you please give an example where double f(double); wouldn't work?

#include <math.h>

double (*pointer)(double) = sin;
double function(double);   // This declares the existence of 'function()'

This is at file scope; it could also be in a block of code, such as inside a function. The pointer to function notation works as you intend. The plain function simply declares a function — not variable that holds a pointer to function.

The only places where the notations are (loosely) equivalent is inside a function argument list:

Declarations:

double integrate(double lo, double hi, double (*function)(double));
double differentiate(double lo, double hi, double function(double));

Definitions:

double integrate(double lo, double hi, double (*function)(double))
{
    ...
}

double differentiate(double lo, double hi, double function(double))
{
    ...
}

The function or function pointer parameters could be used interchangeably in these declarations and definitions, but only in the parameter list — not in the body of the function.

Because the explicit 'pointer to function' notation works everywhere and the other notation only works in a very limited set of places, you should generally use the explicit 'pointer to function' notation, even though it is a little more verbose.

like image 75
Jonathan Leffler Avatar answered Jan 10 '23 10:01

Jonathan Leffler