Reputation: 194
I have the following C Code:
#include <stdio.h>
int max(int x, int y, int (*compare)(int, int))
{
return (*compare)(x,y) ? x : y;
}
int greater_than(int x, int y)
{
if(x > y) return 1;
else return 0;
}
int main(void) {
printf("%d",max(6,7,greater_than));
}
It's just there to test function pointers. But the code still works the same even if i dont use int (*compare)(int,int)
but int compare(int,int)
. It also works if I don't dereference the function pointer or if use int compare(int,int)
but still dereference. It also doesn't make a difference if I pass greater_than
or &greater_than
. Why is this?
With regards Nova
Upvotes: 1
Views: 298
Reputation: 36
Great answer given by Lundin before. Rep too low to comment, so I'll put this here as extra. I saw the link on a similar post here on stackoverflow, I liked the tutorial.
Origin of link to tutorial is this question: How do you pass a function as a parameter in C?
Function pointer tutorial mentioned in the above: http://www.newty.de/fpt/index.html
Hope I'm not being presumptuous, I liked it, maybe it will make for a pleasant read for you as well.
Upvotes: 0
Reputation: 213842
These 2 versions are equivalent:
int max(int x, int y, int (*compare)(int, int))
int max(int x, int y, int compare(int, int))
Just like arrays passed as parameters to functions "decay" into pointers to the first element, similar "decay" happens to functions. They decay into function pointers. The standard says
A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’
So the second (obscure) version above gets silently translated by the compiler into the first version. But there is never a reason to declare a function inside a parameter list, so this whole issue is quite exotic.
As for why compare(x,y)
works as fine as (*compare)(x,y)
or for that matter (*****compare)(x,y)
, it is because whenever you use either a function name or function pointer, you always get a function pointer. If you try to de-reference the function pointer, you get the function. Which again bounces back implicitly into a function pointer.
See Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?
Beginners and veterans all alike can safely forget about the above obscure rules, and just do this:
int max(int x, int y, int (*compare)(int, int))
{
return compare(x,y) ? x : y;
}
Or better yet, use typedef:
typedef int compare_t (int, int);
...
int max(int x, int y, compare_t* compare)
{
return compare(x,y) ? x : y;
}
Upvotes: 4