什么情況需要指定鏈接庫?
在解釋之前,先回顧一下。//來源:公眾號【編程珠璣】
//https://www.yanbinghu.com
#include
#include
int?main(void)
{
????int?b?=?2;
????double?a?=?pow(b,b);
????printf("%f\n",a);
????return?0;
}
代碼本身比較簡單,pow(x,y)用于計算x的y次冪。這里由于pow函數(shù)并不在lib庫中,默認情況下,編譯的時候只鏈接了libc庫,因此如果不指定鏈接庫,則會報錯:$?gcc?-o?test?test.c
/tmp/ccKDgtzz.o:?In?function?`main':
test.c:(.text 0x22):?undefined?reference?to?`pow'
collect2:?error:?ld?returned?1?exit?status
從報錯信息來看,我們知道是找不到pow函數(shù)的定義。通過man手冊也可以查看到,編譯是需要包含頭文件math.h和鏈接數(shù)學(xué)庫的:$?man?pow
???????#include?
???????double?pow(double?x,?double?y);
???????float?powf(float?x,?float?y);
???????long?double?powl(long?double?x,?long?double?y);
???????Link?with?-lm.
即像下面這樣是可以的:$?gcc?-o?test?test.c?-lm
$?./test
4.000000
gcc在編譯的時候默認鏈接的是libc庫,其他庫需要手動指定。但是,看下面的代碼://來源:公眾號【編程珠璣】
//作者:守望先生
#include
#include
int?main()
{
????int?b?=?2;
????double?a?=?pow(b,b);
????std::cout::endl;
????return?0;
}
編譯運行:$?g ?-o?test?test.cpp
$?./test
4
我們并沒有手動指定鏈接庫,但是卻可以編譯過!
那么,問題來了!
為何在C 中使用pow函數(shù)不需要手動指定鏈接數(shù)學(xué)庫libm,而C里面卻需要呢?為了解答這個問題,我們必須知道C 的程序中,到底有沒有鏈接libm庫。如何查看呢?還記得在《linux常用命令-開發(fā)調(diào)試篇》中提到的ldd嗎?它可以查看當前程序鏈接了哪些動態(tài)庫:$?ldd?test
????linux-vdso.so.1?=>??(0x00007ffd41bda000)
????libstdc .so.6?=>?/usr/lib/x86_64-linux-gnu/libstdc .so.6?(0x00007f6230cca000)
????libm.so.6?=>?/lib/x86_64-linux-gnu/libm.so.6?(0x00007f62309c1000)
????libc.so.6?=>?/lib/x86_64-linux-gnu/libc.so.6?(0x00007f62305f7000)
????/lib64/ld-linux-x86-64.so.2?(0x00007f623104c000)
????libgcc_s.so.1?=>?/lib/x86_64-linux-gnu/libgcc_s.so.1?(0x00007f62303e1000)
看到?jīng)]有,除了鏈接了最基本的libstdc 庫,還鏈接了libc和libm庫!也就是說,雖然沒有手動指定鏈接,但是實際上還是鏈接了。但是這是什么時候鏈接上的呢?我們再看libstdc 的鏈接庫發(fā)現(xiàn):$?ldd?/usr/lib32/libstdc .so.6
????linux-gate.so.1?=>??(0xf7f92000)
????libm.so.6?=>?/lib/i386-linux-gnu/libm.so.6?(0xf7da6000)
????libc.so.6?=>?/lib/i386-linux-gnu/libc.so.6?(0xf7bf0000)
????/lib/ld-linux.so.2?(0xf7f94000)
????libgcc_s.so.1?=>?/lib/i386-linux-gnu/libgcc_s.so.1?(0xf7bd3000)
看見沒有!原來是libstdc 已經(jīng)鏈接了libm庫,這也就解釋了為什么C 代碼中不需要手動指定鏈接數(shù)學(xué)庫libm。總結(jié):
通過前面的內(nèi)容我們總結(jié)如下:- C代碼編譯時,通常會默認鏈接libc庫
- C 代碼編譯時,通常會默認鏈接libstdc 庫
- 由于libstdc 中有依賴一些數(shù)學(xué)函數(shù)或者libc庫中的函數(shù),因此默認鏈接了libc庫和libm庫。
作者:守望先生來源:編程珠璣版權(quán)歸原作者所有,如有侵權(quán),請聯(lián)系刪除。