2015-11-12 46 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