为什么它不需要链接libm?

sny*_*nyh 4 c c++ gcc libm

#include <math.h>
#include <stdio.h>
int main()
{
   printf("%f", roundf(3.14));
}
Run Code Online (Sandbox Code Playgroud)

我编译上面的代码(没有使用-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)
Run Code Online (Sandbox Code Playgroud)

为什么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

jma*_*man 6

作为优化,编译器将在编译时计算该值并使用常量,因此不会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
Run Code Online (Sandbox Code Playgroud)

您可以看到roundf()生成的程序集中没有调用.(您可以使用它生成gcc -S filename.c并读取生成的filename.s文件).