15

可能重复:
gcc:为什么需要 -lm 标志来链接数学库?

一般来说,为了使用除包含头文件之外的任何数学函数,math.h您必须使用链接器选项 -lm 进行链接。-l这意味着搜索特定库的链接器选项libm.o

我的问题是

为什么 GCC 默认不包含这个库?是因为该库大量使用数学协处理器并且需要添加额外的代码来初始化浮点初始化(我可能在这里使用了错误的术语)?

笔记

我刚刚查看了链接http://stackoverflow.com中提到的所有答案。这对我来说没有多大意义。归因于三个基本原因

  1. 标准库保证可用。显式链接其他 posix 库(如 pthread)是有意义的,但为什么我们必须为标准库进行显式链接。甚至历史原因也不是很清楚。
  2. 为什么 libm 与 libc 分离?
  3. 为什么我们仍然在最近的 gcc 编译器中继承这些行为?它实现了怎样的简单性?这是我测试的,没有 libm 和 libm。没有 libm 的那个,我写了我自己的 Pow 版本

这是示例

abhibhat@abhibhat-VirtualBox:~/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;
    }
abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ gcc Test_withlibm.c -lm -o Main_withlibm.o
abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ gcc Test_withoutlibm.c -o Main_withoutlibm.o
abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ objdump -d Main_withoutlibm.o|wc -l
261
abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ objdump -d Main_withlibm.o|wc -l
241
4

3 回答 3

11

这是为了适应无法或不需要浮点数学的系统(主要是嵌入式)。这确实有点历史,但不要忘记,gcc大多数其他 C 编译器都是在 386SX 被认为是高性能处理器的时候编写的。

举个例子,当我还在嵌入式计算领域工作时,我们使用标准编译器(Microsoft 和 Borland)为我们的处理器(Z80、80186 和 68030)生成代码。如果编译器默认链接到数学库,我们就会遇到麻烦,因为我们的系统都没有浮点功能,甚至不需要它们。

的确,30年后看起来很傻,但当时的理由是合理的。

于 2012-04-29T12:58:28.450 回答
1

您可能需要许多库,而libm这只是其中之一。
对于其中的每一个,您可能会问为什么默认情况下不包含它。

也许libm比其他人更有用,但是,C 更喜欢保持简单——你想要一个库,用-l它来使用它。

于 2012-04-29T11:24:26.197 回答
1

历史原因

原因libclibm分开并且您必须-lm在命令行上指定是历史原因,因为libmFortran 编译器也使用了 。

于 2012-04-29T12:18:53.693 回答