我在使用CC 5.10编译的Solaris 5.10 64位上有以下C代码,标志为 -m64 -KPIC -x04
header.h
typedef struct functions
{
double (* pfComputeGeneric) (myStruct *, myStruct *, double, double *, int);
} functions;
...
double myCompute(myStruct *, myStruct *, double, double *, int);
由source.c
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);
source.c 中的代码运行正常(没什么奇怪的),直到我通过函数指针 pfCompute 进入 myCompute ,其中 px1 被破坏。我不知道为什么。
通过直接调用 myCompute 来通过 pfCompute 替换调用解决了这个问题。
删除 -x04 选项也解决了这个问题。
我查看了this question的答案,但我确定我没有弄乱指针大小。
答案 0 :(得分:1)
我认为这确实是 -x04 的问题。当我看到组合电话时,我看到了:
...
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 用于存储函数的第一个参数,因此进行了更改。