#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/

10-10 18:22