我在Solaris 5.10 64位的CC 5.10上使用标志-m64 -KPIC -x04编译了以下C代码
头文件
typedef struct functions
{
double (* pfComputeGeneric) (myStruct *, myStruct *, double, double *, int);
} functions;
...
double myCompute(myStruct *, myStruct *, double, double *, int);
源代码
double myCompute(myStruct * px1, myStruct *px2, double d1, double *pd1, int i1)
{
// Do stuff with px1
}
...
myStruct *pxStruct = alloc(...);
functions *pxFunctions = alloc(...);
pxFunctions->pfComputeGeneric = myCompute;
...
double dResult += pxFunctions->pfComputeGeneric(pxStruct, pxStruct, 0.0, NULL, 0);
直到我通过函数指针pfCompute输入myCompute进入px1为止,source.c中的代码才能正常运行(无怪异)。我不知道为什么
通过直接调用myCompute替换pfCompute的调用可以解决此问题。
删除-x04选项也可以解决此问题。
我看了this question的答案,但是我确定我不会弄乱指针大小。
最佳答案
我认为这确实是-x04的问题。当我查看assemby调用时,我看到:
...
0x0000000000987eb2: myCaller+0x081a: movq 0xfffffffffffffe28(%rbp),%rcx
0x0000000000987eb9: myCaller+0x0821: movq $0x0000000000000006,%rax
0x0000000000987ec0: myCaller+0x0828: movq 0xfffffffffffffe08(%rbp),%rdi
0x0000000000987ec7: myCaller+0x082f: call *0x0000000000000018(%rdi)
0x0000000000987eca: myCaller+0x0832: addq $0x0000000000000010,%rsp
因此,编译器使用%rdi(!)从pxFunctions获得myCompute的真实地址。并且在64位中,%rdi用于存储函数的第一个参数,因此用于更改。