Do function pointers need an ampersand [duplicate]
Asked Answered
C

3

50

In C/C++, if I have a the following functions:

void foo();
void bar(void (*funcPtr)());

Is there a difference between these two calls:

bar(foo);
bar(&foo);

?

Caesalpiniaceous answered 4/6, 2013 at 11:50 Comment(4)
For extra confusion, bar(*foo); is also equivalent to both of these. And so is bar(*****foo);.Carlinecarling
I prefer &foo, because this makes it explicit that I want a function pointer, and did not just forget to call the function.Trainbearer
Note that the same is not true for method pointers. They require & explicitly.Sisley
It's a shame this question has been marked as a duplicate, because it really isn't. The linked question assumes the number of ampersands doesn't matter and asks for the reason why, while this one avoids the assumption and asks not why but whether an ampersand is required or not. The problem with linking to the earlier question is that the assumption is wrong: as Nikos has pointed out, ampersands are required for obtaining pointers to non-static member functions, where the syntax &ClassName::FunctionName is mandatory.Shrink
G
46

No, there is no difference, since function can be implicitly converted to pointer to function. Relevant quote from standard (N3376 4.3/1).

An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to the function.

Greenheart answered 4/6, 2013 at 11:51 Comment(2)
This is not always the case. Ampersands are required for obtaining pointers to non-static member functions, where the syntax &ClassName::FunctionName is mandatory.Shrink
@AdrianLopez, yes, but question is about free functions, not class member functions.Greenheart
P
8

Is there a difference between these two calls:

No, there is no difference.

Pashto answered 4/6, 2013 at 11:51 Comment(0)
C
2

bar(foo); is called the "short" version

bar(&foo); is how it is officially done

Functionally, there is no difference, however the second options is considered "good practice" by most since that way it is more obvious that foo is actually a function pointer and not an actual function.

This is similar as with arrays. If you have:

int foobar[10]; 

then foobar is an int *, but you can also do &foobar for the same result.

Cryotherapy answered 4/6, 2013 at 11:55 Comment(2)
I don't agree with your "foobar" part. Defined as int foobar[10];, foobar is an int [10] (array of 10 ints) but can be implicitly converted to int * (pointer to (the first) int) as needed ("array decaying"); in particular, sizeof foobar is equal to 10 * sizeof (int), not sizeof (int *). And the other thing, &foobar is an int (*)[10] (pointer to array of 10 ints), which is another type entirely (not convertible to int *).Italian
Edit: But what you "can do" is &foobar[0] (or &(foobar[0])), which, ironically, is just a convenience syntax for &(*(foobar + 0)), i.e. foobar + 0, where foobar is implicitly converted to a pointer to its first element...Italian

© 2022 - 2024 — McMap. All rights reserved.