2012-04-29 75 views
9

可能重複:
gcc: why the -lm flag is needed to link the math library?爲什麼你需要一個明確的`-lm`編譯器選項

一般來說,爲了從包括頭分開使用任何的數學函數文件math.h你必須鏈接鏈接器選項-lm。 -l這裏意味着鏈接器選項來搜索特定的庫libm.o

我的問題是

爲什麼GCC默認不包含這個庫?是因爲庫大量使用數學協處理器,並且需要添加額外的代碼位來初始化浮點初始化(我可能會在這裏使用錯誤的術語)?

注意

我只是回顧了鏈接http://stackoverflow.com提到的所有答案。這對我來說沒有多大意義。有三個基本原因歸因於:

  1. 標準庫保證可用。顯式鏈接像pthread這樣的其他posix庫顯然是有道理的,但爲什麼我們必須爲標準庫做一個明確的鏈接。即使是歷史原因也不是很清楚。
  2. 爲什麼libm與libc分離?
  3. 爲什麼我們仍然在最近的gcc編譯器中繼承這些行爲?它實現了什麼簡單性?這是我測試的,沒有libm和libm。沒有libm中的一個,我寫我自己的戰俘

的版本,這裏是例子

[email protected]:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c "echo {} && echo "-----------------" && cat {}" 
Test_withlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
int main() { 
    int i=20; 
    double output1=pow(2.618033988749895,i); 
    return 0; 
    } 
Test_withoutlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
double Pow(double _X, int _Y) { 
    double _Z = 1; 
    for (; _Y; _X *= _X) { 
    if (_Y & 1) _Z *= _X; 
    _Y >>= 1; 
    } 
    return _Z; 
    } 
int main() { 
    int i=20; 
    double output1=Pow(2.618033988749895,i); 
    return 0; 
    } 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withlibm.c -lm -o Main_withlibm.o 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withoutlibm.c -o Main_withoutlibm.o 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withoutlibm.o|wc -l 
261 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withlibm.o|wc -l 
241 
+2

歷史原因,我想。鏈接器應該很容易不能鏈接未使用的函數。 MSVC不需要libm就可以使用數學函數。 – Joey 2012-04-29 11:14:48

+0

你不需要它與C++。 – Mat 2012-04-29 11:18:02

回答

7

這是適應系統(主要是嵌入式)的浮點數學是不可能或不必要的。這確實是一種歷史,但不要忘記,gcc和大多數其他C編譯器是在386SX被認爲是高性能處理器的時候編寫的。舉個例子,當我還在嵌入式計算領域工作時,我們使用標準編譯器(Microsoft和Borland)爲我們的處理器(Z80,80186和68030)生成代碼。如果編譯器默認鏈接到數學庫,我們將遇到麻煩,因爲我們的系統都沒有浮點功能,甚至不需要它。

確實,30年後似乎很愚蠢,但當時的原因是合理的。

1

有可能要許多圖書館,並且libm只是其中之一。
對於其中的每一個,您可能會問爲什麼它沒有被默認包含。

或許libm比別人更有用,但是,C仍然傾向於保持簡單 - 你需要一個庫,使用-l來使用它。

+5

但'libm'的獨特之處在於它是C標準庫的一部分。 AFAIK,它是C標準庫中唯一沒有默認鏈接的部分。 – 2012-04-29 11:36:34

+1

@OliCharlesworth,好點。如果「標準」和「默認鏈接」是同一件事,那將會很好。 – ugoren 2012-04-29 11:40:44

1

歷史原因

的原因libclibm是分開的,你必須在命令行上指定-lm是歷史的原因,因爲libm也使用Fortran編譯器。

+0

因此,Fortran可以共享相同的libm,C是分離的原因嗎?在連接Fortran程序時,我們必須在使用gcc時使用'-lm'明確地鏈接它? – Abhijit 2012-04-29 12:21:41

相關問題