gpt4 book ai didi

对 pow libm 函数的调用似乎在不与库链接的情况下得到解决

转载 作者:太空宇宙 更新时间:2023-11-04 02:02:44 26 4
gpt4 key购买 nike

我正在编译以下代码:

#include <stdio.h>
#include <math.h>

main() {
int x=2, y=3;
pow(2,3);
pow(x,y);
}

如果我将其编译为“gcc file.c”(即,我没有链接 libm.a),第一次调用“pow”不会产生链接器错误。只有对“pow”函数的第二次调用会生成预期的对 pow 的 undefined reference - 链接器错误。

我想知道第一个电话是如何解决的

最佳答案

您可以在 gdb 中反汇编您的程序以确保。这是在我的机器(cygwin 32,gcc)上发生的事情:

这个程序:

#include <stdio.h>
#include <math.h>

int main() {
int x = 2, y = 3;
pow(x, y);
return 0;
}

生成此代码(注意其中对 pow 的调用):

(gdb) break main
Breakpoint 1 at 0x4011ae: file test.c, line 6.
(gdb) run
...

Breakpoint 1, main () at test.c:6
6 int x = 2, y = 3;
(gdb) disas
Dump of assembler code for function main:
0x004011a0 <+0>: push %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: sub $0x20,%esp
0x004011a9 <+9>: call 0x401250 <__main>
=> 0x004011ae <+14>: movl $0x2,0x1c(%esp)
0x004011b6 <+22>: movl $0x3,0x18(%esp)
0x004011be <+30>: fildl 0x18(%esp)
0x004011c2 <+34>: fildl 0x1c(%esp)
0x004011c6 <+38>: fxch %st(1)
0x004011c8 <+40>: fstpl 0x8(%esp)
0x004011cc <+44>: fstpl (%esp)
0x004011cf <+47>: call 0x401258 <pow>
0x004011d4 <+52>: fstp %st(0)
0x004011d6 <+54>: mov $0x0,%eax
0x004011db <+59>: leave
0x004011dc <+60>: ret
End of assembler dump.

但如果我只有这个:

#include <stdio.h>
#include <math.h>

int main() {
pow(2, 3);
return 0;
}

我得到的是:

Dump of assembler code for function main:
0x004011a0 <+0>: push %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: call 0x401230 <__main>
=> 0x004011ab <+11>: mov $0x0,%eax
0x004011b0 <+16>: leave
0x004011b1 <+17>: ret

非常清楚地显示您对 pow 的调用已被删除,这可能是由于一些死代码优化。您没有使用返回值,而是为常量值调用它 - 我猜编译器认为删除它是安全的。

现在考虑我实际使用 pow-s 返回值:

#include <stdio.h>
#include <math.h>

int main() {
printf("%lf\n", pow(2,3));
return 0;
}

我明白了:

   0x004011a0 <+0>:     push   %ebp
0x004011a1 <+1>: mov %esp,%ebp
0x004011a3 <+3>: and $0xfffffff0,%esp
0x004011a6 <+6>: sub $0x10,%esp
0x004011a9 <+9>: call 0x401240 <__main>
0x004011ae <+14>: fldl 0x403068
0x004011b4 <+20>: fstpl 0x4(%esp)
0x004011b8 <+24>: movl $0x403060,(%esp)
0x004011bf <+31>: call 0x401248 <printf>
=> 0x004011c4 <+36>: mov $0x0,%eax
0x004011c9 <+41>: leave
0x004011ca <+42>: ret

仍然没有调用 pow

然后打印发送到 printf 的堆栈上的值:

(gdb) x /1f $esp+4
0x22abf4: 8

你也可以看看这个:https://gcc.gnu.org/gcc-4.3/changes.html#mpfropts .

关于对 pow libm 函数的调用似乎在不与库链接的情况下得到解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24904458/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com