27

I have seen this definition of a function that receives a function pointer as parameter:

double fin_diff(double f(double), double x, double h  = 0.01) {
  return (f(x+h)-f(x)) / h;
}

I am used to see this definition with an asterisk, i.e.:

double fin_diff(double (*f)(double), double x, double h  = 0.01);

Do you know why the first definition is also valid?

corning
  • 361
  • 5
  • 20
Freeman
  • 5,810
  • 3
  • 47
  • 48
  • 1
    Functions and function pointers have same meaning when used as a function's parameter. – haccks Jul 22 '19 at 10:09
  • 4
    While you need to know about function pointers and such, in C++ you really shouldn't use them yourself if you can avoid it. If you intend to call the function directly, as in the example shown, use templates instead. Otherwise use [`std::function`](https://en.cppreference.com/w/cpp/utility/functional/function). Using templates or `std::function` increases the flexibility by allowing you to pass any kind of callable object with the right signature, like a lambda, functor object, actual function pointer, etc. – Some programmer dude Jul 22 '19 at 10:10
  • 8
    The languages `c` and `c++` are two different languages. Please choose one and remove the other `tag` as the answer is different depending on the language – user3629249 Jul 22 '19 at 19:14

3 Answers3

30

Standard says that these two functions are equivalent as function arguments are adjusted to be a pointer to function arguments:

16.1 Overloadable declarations [over.load]
(3.3) Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (11.3.5).

same in C:

6.7.5.3 Function declarators (including prototypes)
8 A declaration of a parameter as ‘‘function returning type’’ shall be adjusted to ‘‘pointer to function returning type’’, as in 6.3.2.1.

user7860670
  • 35,849
  • 4
  • 58
  • 84
20

Pointers to functions are peculiar. Given a function void f();, you can do

void (*fptr)() = f;
void (*fptr)() = &f;
void (*fptr)() = &&f;
void (*fptr)() = &&&f;

ad infinitum.

Similarly, when you call a function through a pointer to function you can do

fptr();
(*fptr)();
(**fptr)();
(***fptr)();

ad infinitum.

Everything collapses.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • What's the motivation for this? It's not that this infinite chaining is otherwise impossible (consider a pointer whose referenced value contains its own address), but I don't see why all functions should behave this way. – Alexander Jul 23 '19 at 03:25
  • @Alexander -- it's lost in the mists of time. – Pete Becker Jul 23 '19 at 12:39
  • 1
    @Alexander -- seriously, this comes from C, and has, as far as I know, always been the case. I don't know the reason for it. – Pete Becker Jul 23 '19 at 12:41
  • According to James McNellis it's [C++'s best feature](https://www.youtube.com/watch?v=6eX9gPithBo). – Wes Toleman Jul 23 '19 at 15:00
  • I think `&&f`, `&&&f`,... does *not* work. `**fptr` works though. – starriet Aug 29 '22 at 07:54
  • And... FYI who sees this, James McNellis' video @WesToleman mentioned above is just *joking*... – starriet Aug 29 '22 at 07:55
8

If a function parameter is specified as a function declaration then the compiler itself implicitly adjusts the parameter as a function pointer.

It is similar to when a function name is passed as an argument of some other function as for example

fin_diff( func_name, 10.0 );

the compiler again implicitly converts the function designator to a pointer to the function.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335