为什么即使我颠倒了两个参数,这个函数调用仍然有效?

问题描述 投票:0回答:1

我正在研究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) {
....
}

请注意,我在函数调用中颠倒了

nmax
ftol
参数。

令人惊讶的是,

amoeba()
仍然有效。在调试器中单步调试,确认已为
nmax
ftol
分配了正确的值。

我的主例程

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

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

更新

@Binyamin Sharet,我在这里展示了调用

amoeba
之前和
amoeba
中的程序集。它支持你的假设吗?

Before call to <code>变形虫</code>”/></p>

<p><img src=

c linker
1个回答
6
投票

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

例如,函数需要以下参数顺序:

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

如果你切换

nmax
ftol
也没关系,因为堆栈上的顺序是相同的,并且当
amoeba
尝试读取它们时,它不会因为同样的原因而感到困惑。


编辑

阅读反汇编表明我有点偏离,但由于SSE,用于传递浮点变量的指令是

movss
,您可以在添加的两个汇编列表中看到它,一次到
 xmm0
注册(在调用者中),并从
xmm0
(在被调用者中)注册一次。所以你可以用 xmm 寄存器 替换单词 coprocessor-stack 这就是你的情况。

© www.soinside.com 2019 - 2024. All rights reserved.