gcc默认在Mac OS X上的C中链接数学库?

从这个问题: 为什么你必须在C中链接数学库?

我知道C数学库(libm)与C标准库(libc)分离,默认情况下没有链接。

但是当我在mac osx 10.11.1上使用gcc filename.c而不是-lm编译下面的代码时:

 #include  #include  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的新function?

非常感谢!

更新:

我用以下代码更改了代码:

  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库似乎没有在目标文件中链接

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

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

OSX上没有单独的数学库。 虽然许多系统在单独的数学库中将标准C math.h标头中的函数发布,但OSX不会这样做,它是libSystem库的一部分,它总是链接在一起。

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

sqrt是作为内置的编译器提供的,因此不需要链接到库(因为它发生 – 这样做仍然是良好的做法,以便它在其他地方编译)。

按此页面 :

除非指定了-fno-builtin-function (或为单个函数指定了-fno-builtin-function ),否则ISO C90函数[包括sqrt长列表]都被识别为内置函数。 所有这些函数都有前缀为__builtin_相应版本。

如果使用-fno-builtin编译,我会发现链接阶段出现故障。