#include <bits/stdc++.h>
using namespace std;
void test(){
int a = 100;
cout << a << endl;
}
int main()
{
void(*b)() = test;
(*b)(); //expression one
b(); //expression two
return 0;
}
test
is a pointer to function, isn't it? (*b)()
is a correct form, because it is equivalent to function prototype. But Why is it correct to delete a symbol *
? They all produced the right results.
test
is a pointer to function, isn't it?
No, it isn't. test
is a function.
b
is a pointer to function.
But Why is it correct to delete a symbol *?
Because you can also invoke the function call operator on function pointers, and not just functions.
Furthermore, since a function can implicitly convert to a function pointer, this is also equivalent:
(********b)();
What is the difference between these two expressions
One indirects through function pointer and invokes function call operator - which calls the pointed function.
The other invokes function call operator on a function pointer - which implicitly indirects through the pointer and calls the pointed function.
The former requires 3 more characters to write.
test
is the function, b
is a pointer to function (which points to test
); and pointer to function could be used in function-call expression directly.
A pointer to function can be used as the left-hand operand of the function call operator, this invokes the pointed-to function:
Dereferencing a function pointer yields the lvalue identifying the pointed-to function:
int f(); int (*p)() = f; // pointer p is pointing to f int (&r)() = *p; // the lvalue that identifies f is bound to a reference r(); // function f invoked through lvalue reference (*p)(); // function f invoked through the function lvalue p(); // function f invoked directly through the pointer
Dereference on b
like *b
you'll get the pointed function test
. As the effect, (*b)();
and b();
do the same thing, i.e. invoke test
.
test is a pointer to function, isn't it?
test
is not a pointer to a function. It is a function.
To make the difference between a function and a function pointer more visible consider the following code snippet.
using Fn = void();
using FnPtr = void ( * )( );
Fn test;
FnPtr test_ptr = test;
void test()
{
int a = 100;
std::cout << a << std::endl;
}
In this code snippet there are introduced two aliases. The first alias Fn
denotes the function type void()
. The second alias FnPtr
denotes the pointer type void( * )()
.
So this record
Fn test;
declares the function test
while this record
FnPtr test_ptr = test;
declares the function pointer test_ptr
that is initialized by the address of the function test because the function designator test
used as an initializer in this declaration is implicitly converted to a pointer to the function test
. You could rewrite the declaration also the following way
FnPtr test_ptr = &test;
explicitly applying the address of operator.
These two function call expressions
(*b)();
b();
differ only in one aspect.
In the first call there is used a function lvalue. Neither implicit conversion from the lvalue to a function pointer is done.
In the second call there is used a function pointer.
From the C++ 14 Standard (5.2.2 Function call)
- ...For a call to a non-member function or to a static member function, the postfix expression shall be either an lvalue that refers to a function (in which case the function-to-pointer standard conversion (4.3) is suppressed on the postfix expression), or it shall have pointer to function type
Pay attention to that you could call the function also the following way
( *test )();
In this case the function designator is implicitly converted to a pointer to the function and then after applying the operator * an lvalue to the function is obtained. S you may even write
( ******test )();
or
( *&*&*&test )();
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