2015-11-12 45 views
2

从这个问题:Why do you have to link the math library in C?默认情况下,gcc在Mac OS X的C上链接数学库?

我知道C数学库(libm中)从C标准库(libc)分离,而不是默认链接英寸

但是,当我在Mac OSX上10.11.1 编译下面使用gcc filename.c的代码而不-lm

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

int 
main (void) 
{ 
    double x = sqrt (2.0); 
    printf ("The square root of 2.0 is %f\n", x); 
    return 0; 
} 

有没有链接错误和输出可执行文件正常工作。

然后我试图otool -L output

output: 
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1) 
    /opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 

我想知道有没有在Mac上的一些库结构的差异?

或者这是gcc 5.2.0的新功能?

非常感谢!

更新:

我改变了代码:

double in = 0; 
    scanf("%lf", &in); 
    double x = sqrt(in); 

,它仍然不需要-lm

我拆解代码otool -vVt

(__TEXT,__text) section 
_main: 
0000000100000eed pushq %rbp 
0000000100000eee movq %rsp, %rbp 
0000000100000ef1 subq $0x10, %rsp 
0000000100000ef5 pxor %xmm0, %xmm0 
0000000100000ef9 movsd %xmm0, -0x10(%rbp) 
0000000100000efe leaq -0x10(%rbp), %rax 
0000000100000f02 movq %rax, %rsi 
0000000100000f05 leaq 0x82(%rip), %rdi  ## literal pool for: "%lf" 
0000000100000f0c movl $0x0, %eax 
0000000100000f11 callq 0x100000f54    ## symbol stub for: _scanf 
0000000100000f16 movq -0x10(%rbp), %rax 
0000000100000f1a movd %rax, %xmm0 
0000000100000f1f callq 0x100000f5a    ## symbol stub for: _sqrt 
0000000100000f24 movd %xmm0, %rax 
0000000100000f29 movq %rax, -0x8(%rbp) 
0000000100000f2d movq -0x8(%rbp), %rax 
0000000100000f31 movd %rax, %xmm0 
0000000100000f36 leaq 0x55(%rip), %rdi  ## literal pool for: "The square root of 2.0 is %f\n" 
0000000100000f3d movl $0x1, %eax 
0000000100000f42 callq 0x100000f4e    ## symbol stub for: _printf 
0000000100000f47 movl $0x0, %eax 
0000000100000f4c leave 
0000000100000f4d retq 

看来sqrt被调用。那么为什么事情在mac上变得不同呢?

更新

我发现这个问题的结论:C std library don't appear to be linked in object file

它说在OS X上,数学库是libSystem中的一部分:

$ ls -l /usr/lib/libm.dylib 
lrwxr-xr-x 1 root wheel 15 3 Jun 01:39 /usr/lib/[email protected] -> libSystem.dylib 
+1

也许编译器知道'sqrt(2.0)'是(我做的),所以它不必调用库。 –

+0

@BoPersson也许这是真正的原因。你知道C数学库中的编译器无法优化的一些函数吗?我想尝试一下。非常感谢! – Daizy

+0

如果在编译时不知道该值,就会调用该函数,就像它来自某个输入一样。 –

回答

2

OSX上没有单独的数学库。尽管许多系统在单独的数学库中的标准C math.h头文件中提供了函数,但OSX并没有这样做,它是libSystem库的一部分,它始终被链接。

除此之外,如果编译器可以在编译时执行计算,编译器可以优化掉任何这样的调用。

+0

所以这是由于OS X系统而不是gcc编译器造成的? – Daizy

+0

或者C数学库中的'sqrt()'函数实际上不被调用?我怎样才能找到它?谢谢:P – Daizy

0

sqrt是作为内置的编译器提供,因此不需要链接库(因为它发生 - 这样做仍然是一个好的做法,所以它编译在别处)。

this page

的ISO C90函数[一长串包括sqrt]除非指定​​都识别为内置函数(或为单个功能被指定-fno-builtin-function)。所有这些功能都有相应的版本,前缀为__builtin_

如果你用​​进行编译,我期望在链接阶段失败。

+0

我现在累了。添加'-fno-builtin'后仍然没有失败。 – Daizy