亚星娱乐登录彩票 一个有趣却容易忽略的万事博国际链接问题
扫描二维码
随时随地手机看文章
亚星娱乐官网官网平台
在解释之前,先回顾一下。
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include
#include
intmain
(void)
{
int b =2;
double a =pow(b,b);
printf("%f\n",a);
return0;
}
代码本身比较简单,pow(x,y)用于计算x的y次幂。这里由于pow函数并不在lib库中,默认情况下,
$ gcc -o test test.c
/tmp/ccKDgtzz.o:Infunction `main':
test.c:(.text
0x22): undefined referenceto `pow'
collect2:error: ld returned1exit status
从报错信息来看,我们知道是找不到pow函数的定义。通过man手册也可以查看到,万事博国际是需要包含头文件math.h和链接数学库的:
$ manpow
#include
doublepow
(double x,double y)
;
floatpowf
(float x,float y)
;
longdoublepowl
(longdouble x,longdouble y)
;
Link with -lm.
即像下面这样是可以的:
$
gcc -otest test.c -lm
$
./test
4.000000
gcc在万事博国际的时候默认链接的是libc库,其他库需要手动指定。但是,看下面的代码:
//来源:公众号【编程珠玑】
//作者:守望先生
#include
#include
intmain
()
{
int b =2;
double a =pow(b,b);
std::cout
::endl;
return0;
}
万事博国际运行:
$
g -otest test.cpp
$
./test
4
亚星娱乐登录彩票
亚星娱乐登录老虎机
为何在C 中使用pow函数不需要手动指定链接数学库libm,而C里面却需要呢?为了解答这个问题,我们必须知道C 的程序中,到底有没有链接libm库。如何查看呢?还记得在《linux常用命令-开发调试篇》中提到的ldd吗?它可以查看当前程序链接了哪些动态库:
$
lddtest
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)
看到没有,除了链接了最基本的libstdc 库,还链接了libc和libm库!也就是说,虽然没有手动指定链接,但是实际上还是链接了。但是这是什么时候链接上的呢?我们再看libstdc 的链接库发现:
$ 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 已经链接了libm库,这也就解释了为什么C 代码中不需要手动指定链接数学库libm。
总结:
通过前面的内容我们总结如下:- C代码万事博国际时,通常会默认链接libc库
- C 代码 万事博国际 时,通常会默认链接libstdc 库
- 由于libstdc 中有依赖一些数学函数或者libc库中的函数,因此默认链接了libc库和libm库。
作者:守望先生 来源:编程珠玑 版权归原作者所有,如有侵权,请联系删除。