【问题标题】:gcc link the math library by default in C on mac OS X?gcc 默认情况下在 Mac OS X 上的 C 中链接数学库?
【发布时间】:2016-02-14 00:36:02
【问题描述】:

来自这个问题:Why do you have to link the math library in 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/libm.dylib@ -> libSystem.dylib

【问题讨论】:

  • 也许编译器知道sqrt(2.0) 是什么(我知道),所以它不必调用库。
  • @BoPersson 也许这才是真正的原因。你知道一些 C 数学库中编译器无法优化的函数吗?我想试试。非常感谢!
  • 如果值在编译时未知,它必须调用函数,比如它来自某个输入。
  • @BoPersson 好像不行……

标签: c macos compilation linker


【解决方案1】:

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

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

【讨论】:

  • 所以是OS X系统造成的,而不是gcc编译器造成的?
  • sqrt( ) C数学库中的函数实际上没有被调用?我怎样才能找到它?谢谢:P
【解决方案2】:

sqrt 是作为内置编译器提供的,因此不需要到库的链接(碰巧 - 这样做仍然是一种很好的做法,以便它可以在其他地方编译)。

this page:

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

如果您使用 -fno-builtin 编译,我预计链接阶段会失败。

【讨论】:

  • 我刚才累了。添加-fno-builtin后依然没有失败。
猜你喜欢
  • 1970-01-01
  • 2011-11-09
  • 2013-09-06
  • 1970-01-01
  • 2011-10-07
  • 2012-07-13
  • 2011-10-17
  • 2011-05-20
  • 1970-01-01
相关资源
最近更新 更多