I have these two test functions:
int apply_a(int (*fun)(int, int), int m, int n) {
return (*fun)(m,n);
}
int apply_b(int (*fun)(int, int), int m, int n) {
return fun(m,n);
}
they appear to return something different, so why do both of them yield the same result?
int add(int a, int b) {return a + b;}
int res_a = apply_a(add, 2, 3); // returns 5
int res_b = apply_b(add, 2, 3); // returns 5
I would've assumed that one of them would return the pointer address or the pointer itself; rather than the value stored on the pointer...
So why is it doing this?
Because C++ offers syntactic sugar when it comes to handling the address of non-member functions and using pointers to them.
One can get address of such function:
int someFunc(int);
with either:
int (* someFuncPtr)(int) = someFunc;
or:
int (* someFuncPtr)(int) = &someFunc;
There is also syntactic sugar for using such pointer, either call pointed-to function with:
(*someFuncPtr)(5);
or with simplified syntax:
someFuncPtr(5);
(*fun)(m,n)
is the same as fun(m,n)
due to rules in C and C++ that convert functions to pointers to functions.
In C 2011, the rule is clause 6.3.2.1 4: “A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof 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”. In C++, the rule is clause 4.3.
Note that a function designator is not merely an identifier that names a function. It could be an identifier, or it could be another expression. For example, if foo
is the name of a function, it is automatically converted to a pointer to a function by the above. Then, since foo
is a pointer to the function, *foo
is the function. This means you can write:
(*fun)(m,n)
The result is that fun
is automatically converted to a pointer, then *
evaluates to the function, then *fun
is converted back to a pointer, then the function is called. You can continue this and write:
(**************fun)(m,n)
This is the same as fun(m,n)
. Each *
produces the function again, but the compiler automatically converts it back to a pointer. You can continue this battle forever, but the compiler will always win.
In fact, these all have the same effect:
(&fun)(m,n)
( fun)(m,n)
(*fun)(m,n)
It is because you are not returning memory addresses of these values. Calling a function with pointer does not change it's value it's still calling the function. What you can do is return a value to a variable and then get it's memory address such as:
int result = fun(m,n);
cout << "the result " << result << " pointing at " << &result << endl;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With