Reputation: 2569
I was messing around with function pointers, and I noticed something with the following program:
#include <stdio.h>
int operation (int x, int y, int (*fptr)(int, int))
{
int z;
z = (*fptr)(x, y);
return (z);
}
int add(int a, int b) {
return a+b;
}
int main(int argc, char** argv) {
/* This line */ printf("%d\n", operation(1, 2, add));
}
Running this program results in 3, as it should.
However, on the line marked /* This line */
, I noticed that if the line was changed to any of the these other two options, it also resulted in 3:
printf("%d\n", operation(1, 2, *add)
and printf("%d\n", operation(1, 2, &add)
(notice the added asterisk and ampersand).
It also works when I tried things like printf("%d\n", operation(1, 2, *(&add)));
and printf("%d\n", operation(1, 2, &(*add)));
(which I assumed after seeing the above).
I was wondering why this is, and if there is any difference between the two options. Is this undefined behavior and I'm just getting lucky, does the compiler assume that by all of these I mean the same thing, or is there something weird going on here I don't understand?
Upvotes: 2
Views: 96
Reputation: 681
Actually, function names are just labels for memory addresses, which makes them address holders like pointers. So, you can think of function names as pointers in a way. Therefore, it should not be surprising that you can use the same reference operators as you did on pointers.
Upvotes: 0
Reputation: 308120
From the ANSI/ISO 9899-1990 C standard, section 6.2.2.1:
A function designator is an expression that has function type. Except when it is the operand of the sizeof operator 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."
This means that add
by itself is converted to a pointer. &add
is also a pointer, kind of by definition; I think that's why it's explicitly excluded from the paragraph above. And *add
goes through a double conversion, dereferencing the function as a pointer then reinterpreting that as a pointer again.
I don't expect there would be any difference in the compiled code.
Upvotes: 4