I have caught myself accidentally using two different styles of C function pointer definitions in different places and have decided to write a minimal program to test these differences.
The two styles in question are:
int (comp (int))
and
int (*comp)(int)
I wrote a minimal program that uses both of these styles for the same function pointer, one for the declaration of a function and one for the definition of the same function, to see what the compiler would have to say about it.
Declaration:
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
Definition:
int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
int out = a_fn ();
if (comp (out))
out = b_fn ();
return out;
}
As you can (hopefully) see, for the first parameter in the declaration I used the style int (*a_fn)()
, while in the definition of the function, I used the style int (a_fn ())
. I do something similar with the next two arguments.
I speculated that these might be incompatible types, that these styles might be the difference between a pass-by-reference and pass-by-value assignment of the variable, but when I compiled this program the compiler silently and happily compiled it. No errors, no warnings, nothing.
As I've seen very many tutorials advocating for the second style, while I personally prefer the first style for aesthetic purposes, I am interested in what the difference is between these two styles and which is recommended.
Full code example:
#include <stdio.h>
int a ();
int b ();
int a_or_b (int (*a_fn)(), int (b_fn()), int (*comp)(int));
int a ()
{
return 1;
}
int b ()
{
return 2;
}
int comparison (int param)
{
return param;
}
int a_or_b (int (a_fn()), int (*b_fn)(), int (comp(int)))
{
int out = a_fn ();
if (comp (out))
out = b_fn ();
return out;
}
int main (int argc, char **argv)
{
printf ("%i\n", a_or_b (a, b, comparison));
return 0;
}
Function Pointers are pointers(like variable pointers) which point to the address of a function. They actually calling the underlying function when you dereference them like a function call does. The main advantage of a function pointer is that you can pass it to another function as a parameter for example ...
CServer Side ProgrammingProgramming. Function Pointers point to code like normal pointers. In Functions Pointers, function's name can be used to get function's address. A function can also be passed as an arguments and can be returned from a function.
Function pointers in C can be used to create function calls to which they point. This allows programmers to pass them to functions as arguments. Such functions passed as an argument to other functions are also called callback functions.
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.
In a function parameter list, functions get converted to function pointers. The C11 standard, ISO/IEC 9899:2011, §6.7.6.3 Function declarators (including prototypes) says:
¶8 A declaration of a parameter as "function returning type" shall be adjusted to "pointer to function returning type"…
So, as written, the parameters are all treated as 'pointer to function'. It is best to be self-consistent, though.
Note that a function cannot return a function:
¶1 A function declarator shall not specify a return type that is a function type or an array type.
Outside a function declarator (the argument list of a function definition or function declaration), the notations are different:
int (*a_fn)();
int (b_fn());
The first of these declares (defines) a variable called a_fn
— a pointer to a function returning int
with an unspecified (but not variadic) argument list.
The second of these declares the existence of a function called b_fn
that returns an int
with an unspecified (but not variadic) argument list (and has a superfluous set of parentheses; it could be written int b_fn();
and it means the same thing).
Both int (comp (int))
and int (*comp)(int)
are equivalent when used as a function parameters. Function designators are converted to pointers to the function itself.
C11-§6.3.2.1:
A function designator is an expression that has function type. Except when it is the operand of the
sizeof
operator, the_Alignof
operator,65) or the unary&
operator, a function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
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