#include <math.h>
#include <stdio.h>
int main()
{
printf("%f", roundf(3.14));
}
我编译以上代码(未使用-lm),添加了使用ldd a.out,结果是
linux-vdso.so.1 => (0x00007fffab9ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd6da0f8000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd6da4eb000)
为什么a.out没有与libm链接,但可以使用roundf(或类似sqrt的东西)?
我已经使用nm来测试libc.so.6和ld-linux-x86064.so.2,但是所有这些都没有roundf的符号。
我想知道在哪里定义了roundf,或者它已经被编译器内联了?
(使用gcc 4.7.3和gcc 4.6.3进行测试)
答案是http://fedoraproject.org/w/index.php?title=UnderstandingDSOLinkChange
最佳答案
作为一种优化,编译器将在编译时计算出该值并使用一个常量,因此不涉及对roundf()
的调用。您可以通过查看生成的代码来验证这一点:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, %eax
fldl .LC1
fstpl 4(%esp)
movl %eax, (%esp)
call printf
leave
ret
您可以看到在生成的程序集中没有对
roundf()
的调用。 (您可以使用gcc -S filename.c
生成此文件,并读取生成的filename.s
文件)。关于c++ - 为什么不需要链接libm?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16204457/