russellsayshi
russellsayshi

Reputation: 2569

Is there a difference between these ways to get function pointers in C?

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

Answers (2)

Unavailable
Unavailable

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

Mark Ransom
Mark Ransom

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

Related Questions