可能重複:
Why do you have to link the math library in C?爲什麼我必須明確鏈接libm?
當我寫一個使用功能從math.h
庫的程序,那爲什麼我必須明確地鏈接到libm
,即使他們的一部分C標準庫?
舉例來說,當我想用sin()
功能,我需要#include <math.h>
,但我也需要通過-lm
到GCC。但對於標準庫中的任何其他庫,我不必這樣做。爲什麼區別?
可能重複:
Why do you have to link the math library in C?爲什麼我必須明確鏈接libm?
當我寫一個使用功能從math.h
庫的程序,那爲什麼我必須明確地鏈接到libm
,即使他們的一部分C標準庫?
舉例來說,當我想用sin()
功能,我需要#include <math.h>
,但我也需要通過-lm
到GCC。但對於標準庫中的任何其他庫,我不必這樣做。爲什麼區別?
在過去,連接器很慢,將大部分未使用的數學代碼與其他代碼分開,這使得編譯過程變得更快。今天的差異並不大,所以您可以將-lm
選項添加到您的默認編譯器配置中。
請注意,標頭<math.h>
(或任何其他標頭)不包含代碼。它包含有關代碼的信息,具體是如何來調用函數。代碼本身在一個庫中。我的意思是,您的程序不使用「<math.h>
庫」,它使用數學庫並使用<math.h>
標頭中聲明的原型。
實際上,你通常不需要鏈接到大多數數學函數的libm的原因是它們是由你的編譯器內聯的。如果不是這種情況,您的程序將無法在平臺上鍊接。
這與在大多數實現中必須明確鏈接到libpthread
的原因相同。當新的和可怕的東西添加到標準庫時,它通常首先被實現爲一個單獨的附加庫,它覆蓋了舊標準庫實現中符合新需求的版本中的一些符號,同時還添加了大量的新界面。如果某些歷史實現在libm
的浮點打印中有printf
的單獨版本,並且libc
中的「淺」版本缺乏浮點數,我不會感到驚訝。如果我沒有記錯的話,這種實現實際上是在ISO C基本原理文檔中爲小型系統提及和鼓勵的。
當然,從長期來看,將標準庫分離出來會導致比益處更多的問題。最糟糕的部分可能是動態鏈接程序的加載時間和內存使用量增加。
大部分'libm'不可能內聯,除非你的內聯函數的限制是幾KB,或者你已經啓用了像'-ffast-math'這樣的黑客,允許編譯器生成不正確但快速的代碼。 – 2011-03-24 13:48:31
那麼,在x86上,正弦和餘弦在FPU內部實現,並且可以通過一條指令訪問,因此內聯在這裏有很大的意義。一個只使用sin()的程序不需要和x86上的'libm'鏈接,從而隱藏缺失的庫引用。 – 2011-03-24 15:21:25
你確定FPU'sin'指令可以直接執行'sin()'嗎?如果我沒有弄錯,那麼首先需要一個非平凡的論證減少步驟。 – 2011-03-24 17:01:59