2

I know the function name in ASM is just the address of the first instruction in the function.

So I think the function name should be the right value in c++. But why I also can get the address of the function name. And both can be assigned to the function pointer like these:

typedef int (*Func)();
int A(){
    return 1;
}
int main()
{
    Func* f = &A;
    f = A;
    (*f)();
}

So I want to know what is the function name in CPP and the difference between the function name and the address of the function name;

Update: Because of my fault, I submit the wrong code, the code I want to ask is:

typedef int (*Func)();
int A(){
    return 1;
}
int main()
{
    Func f = &A;
    f = A;
    (*f)();
}
YD Zhou
  • 317
  • 2
  • 8
  • 1
    Functions follow different rules from variables. You can take the address of a function, which is the same as just letting it decay: `Func* f = A;`. – Passer By Jan 05 '22 at 03:37
  • Like arrays, functions decay to pointers. Your two assignments are the same. Both assignments store the address of the first instruction. – Drew Dormann Jan 05 '22 at 03:40
  • 1
    just one of those nuances – mukunda Jan 05 '22 at 03:48
  • Alas, the function name is not the bytes of the machine code that the function name refers to, and which could possibly be programmatically changed perhaps. The function name is not the AST of the function. Both of which would be nice to have had, in some scenarios. – Eljay Jan 05 '22 at 03:49

2 Answers2

4

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:

  1. 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.

  2. 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.

Jason
  • 36,170
  • 5
  • 26
  • 60
0

So I want to know what is the function name in CPP

Function name is an expression. The type of the expression is a function type.

&A is an addressof expression. The type of the expression is a pointer to function type.

eerorika
  • 232,697
  • 12
  • 197
  • 326