Lets take a look at line by line explanation of your code snippet.
typedef int (*Func)(); //Statement 1: This means Func is just another name for a "pointer to a function that takes no parameter and returns an int
//Here you are defining a function named A that takes no parameter and returns an int
int A(){
return 1;
}
int main()
{
Func* f = &A;//Statement 2
f = A;//Statement 3
(*f)();//statement 4
}
Statement 1
Here we have the statement
typedef int (*Func)();
This means, that
Func
is just another name for a pointer to a function that takes no parameter and returns an int
. Technically this is nothing but int(*)()
.
Statement 2
Here we have the statement,
Func* f = &A;
On the left hand side we are defining an object named f
of type Func*
. That is, the type of f
is pointer to Func
. But since Func
itself is a pointer to a function that takes no parameter and returns an int
.
This implies that the type of f
is
a pointer to a pointer to a function that takes no parameter and returns an int
. Technically it is nothing but int(**)()
.
Now we are going to look at the right hand side of statement 2. But for that you must know this:
The type of A
is int()
which is called a function type.
So when you wrote the expression &A
this means you'll get:
a pointer to a function type. Which in this case is int(*)()
.
Why Problem in Statement 2
So essentially on the left hand side you have an expression of type int(**)()
while on the right hand side you have an expression of type int(*)()
. So there is a mismatch in the types and this is exactly what the error says:
error: cannot convert ‘int (*)()’ to ‘int (**)()’ in initialization
Statement 3
Here we have the statement,
f = A;
Here on the left hand side you have an expression of type int(**)()
as explained in above(in statement 2's explanation). In particular, f
has the type int(**)()
While on the right hand side we have expression of type int()
as already explained above(in statement 2's explanation). In particular, since A
is a function type and has the type int()
.
Why Problem in Statement 3
Here again there is mismatch in types of expressions on the left hand side and the right and side which is exactly what the error says:
error: cannot convert ‘int()’ to ‘int (**)()’ in assignment
Statement 4
Here we have the statement
(*f)();
Here you are doing 2 things:
Dereferencing the pointer f
. But since f
's type is int(**)()
, the result of dereferencing f
will be int(*)()
which is nothing but a pointer to a function that takes no parameter and returns an int
.
Next, you are calling the function through that resulting pointer. In this case there is no syntactic error. That is there is there is no syntactic error in statement 4.
Edit
Now since you have edited statement 2 to Func f = &A;
i will explain this one.
In this case on the left hand side the type of f
is Func
. But since Func
is nothing but int(*)()
. This means :
f
itself is a pointer to a function that takes no parameter and returns an int
. That is f
has type int(*)()
.
Now on the right hand side you have &A
. But note as i already explained, A
is a function type which is int()
in this case. So this means, when you write &A
:
&A
is a pointer to a function that takes no parameter and returns an int
. This means, &A
has type int(*)().
So essentially the types on the right hand side and left hand side match and there is no error in this case.