I have a problem with understanding some C++ syntax combined with function pointers and function declarations, that is:
Usually when we want to declare a type of function we make something like:
typedef void(*functionPtr)(int);
and this is fine for me. From now on functionPtr is a type, that represents pointer to the function, that returns void and takes int by a value as an argument.
We can use it as follows:
typedef void(*functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
And we get 5
printed on a screen.
we have got pointer to function fun
, we assign some existing pointer to function - function
and we execute this function by a pointer. Cool.
Now as I read in some books, function and pointer to function are treated somehow the same, so in fact after declaration of function()
function everytime we say function we mean real function and pointer to function at the same type, so following compiles and every instruction gives the same result (5 printed on a screen):
int main() {
functionPtr fun = function;
fun(5);
(*fun)(5);
(*function)(5);
function(5);
return 0;
}
So now as long as I can imagine, that pointers to functions and functions are pretty much the same, then it's somehow fine for me.
Then I though, if pointer to function and real function is the same, then why cannot I do following:
typedef void(functionPtr)(int); //removed *
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr fun = function;
fun(5);
return 0;
}
This gives me following error:
prog.cpp:12:14: warning: declaration of 'void fun(int)' has 'extern' and is initialized functionPtr fun = function;
therefore I understood, that for some reason compiler now understands, that fun is already existing function. Then I tried following:
int main() {
functionPtr fun;
fun(5);
return 0;
}
And I got linking error. I somehow understand, that as compiler now treats fun as already existing function, then due to the fact, that fun is nowhere defined, I will get linking error. Therefore I changed the name of the variable:
typedef void(functionPtr)(int);
void function(int a){
std::cout << a << std::endl;
}
int main() {
functionPtr function;
function(5);
return 0;
}
So now function in main shadows global name function, so function(5)
is used from declaration functionPtr function;
It works fine and prints 5 on the screen.
So now I am shocked. Why did this happen? Also misleading thing is, that when function pointer is declared like this:
typedef void(*functionPtr)(int);
i can create function of type functionPtr in following manner:
functionPtr function(int a){
std::cout << a << std::endl;
}
whereas, when declaring something like:
typedef void(functionPtr)(int);
makes this:
functionPtr function(int a){
std::cout << a << std::endl;
}
being interpreted by a compiler as function returning function. If this is so, why previous declaration (typedef void(functionPtr)(int);
) knew, that this is a function returning void and not function returning functionPtr?
Could someone please explain what is really happening underhood for me?
I am using g++ C++ compiler with C++14 option enabled.
See Question&Answers more detail:os