为什么这个函数调用工作,即使我倒两个参数?

时间:2012-02-22 18:17:50

标签: c compiler-construction linker

我正在研究 Numerical Recipes 中的Nelder-Mead算法的变体,它允许用户指定要进行的最大目标函数调用次数。

从我的主程序,这里是我如何调用实现Nelder-Mead算法的amoeba()函数:

amoeba(p,y,params->ndim,params->tol,params->nmax,internal_funk,&nfunc);

但这是如何实施的:

void amoeba(float **p, float y[], int ndim, unsigned nmax, float ftol, float (*funk)(float []), int *nfunk) {
....
}

请注意,我在函数调用中反转了nmaxftol个参数。

令人惊讶的是,amoeba()仍有效。在调试器中单步执行此操作可确认已将正确的值分配给nmaxftol

我的主例程#include是一个头文件,它定义了amoeba()例程的签名,并且编译主例程没有产生任何错误。但是,amoeaba()源文件包含该标题(我的错误),因此编译器也没有生成任何错误。

那么为什么我的链接程序仍然可以正常运行,即使参数没有以正确的顺序给出?

更新

@Binyamin Sharet,我在调用amoeba之前和amoeba之前就在这里展示了大会。它是否支持您的假设?

Before call to <code>amoeba</code>

Inside <code>amoeba</code>

更新2

@Binyamin Sharet肯定,这是:

enter image description here

1 个答案:

答案 0 :(得分:6)

原因可能是,因为浮点参数不是在堆栈上传递,而是在协处理器堆栈上传递,所以这两者的顺序无关紧要。

例如,函数需要这个参数顺序:

   |         p              |                             |
   |         y              |                             |
   |         ndim           |                             |
   |         nmax           |                             |
   |         funk           |                             |
   |         nfunk          |          ftol               |
   +------------------------+-----------------------------+
   |        stack           |        coprocessor stack    |

如果你切换nmaxftol并不重要,因为堆栈上的顺序是相同的,当amoeba尝试读取它们时,它没有'因同样的原因而感到困惑。


修改

读取反汇编显示我有点偏离,但由于SSE,用于传递float变量的指令是movss,您可以在添加的assemblt列表中看到,一次到xmm0注册(在调用者中),一次来自xmm0(在被调用者中)。所以你可以用 xmm register 替换 coprocessor-stack 这个词,这就是你的情况。