我在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用于存储函数的第一个参数,因此用于更改。

10-05 22:43