【问题标题】:Why does this function call work even though I inverted two parameters?即使我反转了两个参数,为什么这个函数调用仍然有效?
【发布时间】:2012-02-22 18:17:50
【问题描述】:

我正在研究一种来自 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

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

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

更新

@Binyamin Sharet,我在调用amoebaamoeba 之前在这里展示了这个程序集。它支持你的假设吗?

更新 2

@Binyamin Sharet 当然,这里是:

【问题讨论】:

  • 它们是唯一值并且在函数内部仍然显示正确的值?
  • 首先,启用警告...
  • @DanF 是的。甚至不是同一类型。 nmax 为 1000,ftol 约为 5e-5。 @yi_H,这是我启用的警告:-Wall -Wextra -Wshadow -Wswitch-default -Wswitch-enum -Wconversion
  • 看看你的代码,是的,它看起来就是这样。指令movss 用于移动浮点数(在 SSE 中引入)。好像我有点不对劲,因为它将数字移动到一个特殊的寄存器,而不是协处理器堆栈,但这是同一个想法......
  • 顺便说一句,你发布的第一个反汇编很好,我看错了,对不起。

标签: c compiler-construction linker


【解决方案1】:

原因大概是因为浮点参数不是传到栈上的,而是传到协处理器栈上的,所以这两者的顺序无关紧要。

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

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

如果你切换nmaxftol没关系,因为堆栈上的顺序是一样的,当amoeba试图读取它们时,它不会因为相同而感到困惑原因。


编辑

阅读反汇编表明我有点跑题了,但是因为SSE,用于传递浮点变量的指令是movss,你可以在你添加的两个汇编列表中看到它,一次是@ 987654328@注册(在调用者中),一次从xmm0(在被调用者中)。所以你可以用 xmm registers 替换词 coprocessor-stack ,这就是你的情况。

【讨论】:

  • 不用说,但这只是偶然的:很可能,在不同的平台上,它不会工作
  • 我完全同意,我想写“你很幸运”但后来删除了它,因为我认为它没有那么幸运。可能机会是正确的词。
  • Wellll....我在我们的单元测试中发现了这一点,但真正的代码运行在一个没有硬件支持浮点的嵌入式平台上...哎呀 ;-)
猜你喜欢
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
相关资源
最近更新 更多