以前在使用函数指针的时候,没有弄明白函数名和函数指针类型的区别,今天做了个小测试,总结一下测试结果。
int32_t mytest(int32_t id)
{
printf("my test\n");
return 0;
}
typedef int32_t (*P_FUN)(int32_t);
P_FUN t /*0x00499e0c*/ = mytest /*0x00519f80*/ ;
P_FUN p /*0x00499e0c*/ = &mytest;
P_FUN f /*0x00499e0c*/ = *p;
mytest(100);
p(0);
f(1);
printf("%08x", *(int32_t*)p); //->0x08017fe9
调试发现以上三种均可调用到函数mytest,但是t、p、f的值不一样,关系为 t != (p == f),
查看vs反汇编
int32_t mytest(int32_t id)
{
00519F80 push ebp
00519F81 mov ebp,esp
......
P_FUN t = mytest;
0051A2BC mov dword ptr [ebp-20h],offset mytest (499E0Ch)
P_FUN p = &mytest;
0051A2C3 mov dword ptr [ebp-2Ch],offset mytest (499E0Ch)
P_FUN f = *p;
0051A2CA mov eax,dword ptr [ebp-2Ch]
0051A2CD mov dword ptr [ebp-38h],eax
根据上面的代码,我认为,当在程序中直接使用函数名mytest的时候,mytest的值是函数代码的起始地址,将mytest赋值到函数指针变量的时候编译器取得一个跟函数相关的地址,将其保存到了函数指针中,我们使用函数指针类型实际上使用的是这个地址而不是函数代码地址,调用函数的时候会根据这个指针通过某种方法找到函数代码的起始地址进行函数调用。
以上只是我的一点看法,其中函数指针中存的值(printf("%08x", *(int32_t*)p); //->0x08017fe9 )指向的内存到底存的是什么还是不太清楚(难道是函数首地址0x00519f80??),有待求证。