在编译时为什么要加上 –lm ?

您所在的位置:网站首页 lm是什么意思啊 在编译时为什么要加上 –lm ?

在编译时为什么要加上 –lm ?

#在编译时为什么要加上 –lm ?| 来源: 网络整理| 查看: 265

Linux 中常用链接来解决一些库函数的问题。在编译时链接可以生成可执行文件。了解一些链接的基本过程,能让我们在开发中减去不少的麻烦!

编译时使用 gcc -lm

程序功能很简单,下面的示例展示了exp()函数的用法。

(代码一)

#include #include //exp int main(int argc, char const *argv[]){ //double x = 0; printf("The exponential value of %lf is %lf\n", 0, exp(0)); printf("The exponential value of %lf is %lf\n", 0+1, exp(0+1)); printf("The exponential value of %lf is %lf\n", 0+2, exp(0+2)); return(0); }

编译结果:

在这里插入图片描述我们再来看下面这种情况: (代码二)

#include #include //#define X 0 int main(int argc, char const *argv[]){ double x = 0; printf("The exponential value of %lf is %lf\n", x, exp(x)); printf("The exponential value of %lf is %lf\n", x+1, exp(x+1)); printf("The exponential value of %lf is %lf\n", x+2, exp(x+2)); return(0); }

编译输出: 在这里插入图片描述 同样的编译方法却编译不过了,提示对‘exp’未定义的引用。

来看看man手册exp函数的使用: 在这里插入图片描述 发现exp函数除了需要包含头文件math.h外,编译时还需要使用-lm链接。

编译时在包含链接-lm,看看是否编译通过:

在这里插入图片描述库链接一般放在命令行结尾。

问题

两段代码同样都调用了exp函数,为什么一个需要链接,一个不需要链接呢?

我们可以观察到,代码一调用exp传入的参数是常量为 0 。代码二调用exp传入的参数是变量 x,那么对于代码一会不会在运行之前就计算好了呢?

来看看它们的汇编代码: (代码一) 在这里插入图片描述在这里插入图片描述 第一段代码没有看到调用exp的身影。实际上,通过汇编代码可以看到,当传入参数为常量时,就已经计算好了值,最后根本不需要调用exp函数。

(代码二)

在这里插入图片描述在这里插入图片描述 汇编的具体细节我们无需尽知,变量型的参数,其值在运行时确定,因此需要调用,第二段代码call exp指令调用了exp函数。

ldd命令查看链接库

代码一:

在这里插入图片描述 在Linux平台上最广泛使用的C函数库是glibc,其中包括C标准库的实现。几乎所有C程序都要调用glibc的库函数,所以glibc是Linux平台C程序运行的基础。glibc提供一组头文件和一组库文件,最基本、最常用的C标准库函数和系统函数在libc.so库文件中,几乎所有C程序的运行都依赖于libc.so (例如 printf)

代码二:

在这里插入图片描述 使用math.h中声明的库函数还有一点特殊之处,gcc命令行必须加-lm选项,因为数学函数位于libm.so库文件中(这些库文件通常位于/lib目录下),-lm选项告诉编译器,我们程序中用到的数学函数要到这个库文件里找。

总结

调用函数是否需要链接,可以使用命令“man 3 函数名“查看,如果需要链接库,最后都有说明。调用包含于libc库中的函数不需要链接。

在这里插入图片描述 (微信公众号: 程序猿编码 ) 在这里插入图片描述 (添加本人微信,备注加群,进入程序猿编码交流群,领取学习资料,获取每日干货)

欢迎关注微信公众号“程序猿编码”,这里Linux c/c++ 、Go语言、数据结构与算法、网络编程相关知识,常用的程序员工具。还有汇聚精炼每日时政、民生、文化、娱乐新闻简报,即刻知晓天下事!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3