49

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);

?

Baruch
  • 20,590
  • 28
  • 126
  • 201
  • 11
    For extra confusion, `bar(*foo);` is also equivalent to both of these. And so is `bar(*****foo);`. – Mike Seymour Jun 04 '13 at 13:40
  • 4
    I prefer `&foo`, because this makes it explicit that I want a function pointer, and did not just forget to call the function. – sp2danny Oct 14 '14 at 13:22
  • 3
    Note that the same is not true for method pointers. They require & explicitly. – KeyC0de Sep 22 '18 at 19:43
  • 1
    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. – Adrian Lopez Dec 07 '20 at 18:15

3 Answers3

44

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.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • 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. – Adrian Lopez Dec 07 '20 at 18:21
  • @AdrianLopez, yes, but question is about free functions, not class member functions. – ForEveR Dec 07 '20 at 18:47
8

Is there a difference between these two calls:

No, there is no difference.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

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.

jamylak
  • 128,818
  • 30
  • 231
  • 230
Maarten
  • 309
  • 5
  • 14
  • 11
    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 *`). – gx_ Jun 04 '13 at 12:32
  • 4
    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... – gx_ Jun 04 '13 at 13:08