gcc 为什么需要显式的'-lm'编译器选项?[duplicate]

vmdwslir  于 2022-11-12  发布在  其他
关注(0)|答案(3)|浏览(194)

此问题已存在

10年前就关门了。

可能重复:

gcc: why the -lm flag is needed to link the math library?
一般来说,为了使用任何数学函数,除了包含头文件math.h之外,还必须使用链接器选项-lm进行链接。这里的-l是指用于搜索特定库libm.o的链接器选项。
为什么GCC默认包含这个库?是因为这个库大量使用了数学协处理器,并且需要添加额外的代码来初始化浮点初始化(我可能在这里使用了错误的术语)吗?

备注

我刚刚复习了问题 * gcc: why is the -lm flag needed to link the math library? * 中提到的所有答案。这对我来说没有多大意义。有三个基本原因:
1.标准库保证是可用的。显式链接其他POSIX库如 pthread 是有意义的,但为什么我们必须为标准库做显式链接呢?甚至历史原因也不是很清楚。
1.为什么 libmlibc 分开?
1.为什么我们仍然在最近的GCC编译器中继承这些行为?它实现了什么样的简单性?下面是我在没有 libm 和有 libm 的情况下测试的结果。对于没有 libm 的编译器,我编写了我自己的Pow()版本。
下面是一个示例:

cd ~/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;
    }

$ gcc Test_withlibm.c -lm -o Main_withlibm.o
$ gcc Test_withoutlibm.c -o Main_withoutlibm.o
$ objdump -d Main_withoutlibm.o|wc -l

261

$ objdump -d Main_withlibm.o|wc -l

241
41ik7eoe

41ik7eoe1#

它是为了适应那些不可能或不需要浮点运算的系统(主要是嵌入式系统)。它确实有点历史意义,但不要忘记,gcc和大多数其他C编译器是在386SX被认为是高性能处理器的时代编写的。
给予个例子,当我还在从事嵌入式计算工作时,我们使用标准编译器(微软和Borland)为我们的处理器(Z80、80186和68030)生成代码。如果编译器默认链接到数学库,我们就会遇到麻烦,因为我们的系统都没有浮点功能,甚至不需要浮点功能。
这是真的,30年后,这似乎是愚蠢的,但原因是健全的,在当时。

1szpjjfi

1szpjjfi2#

历史原因

libclibm分开以及必须在命令行上指定-lm的原因是历史原因,因为libm也被Fortran编译器使用。

72qzrwbm

72qzrwbm3#

您可能需要许多库,libm只是其中之一。
对于其中的每一个,您可能会问为什么默认情况下不包括它。
也许libm比其他的更有用,但是C仍然喜欢保持简单。如果你需要一个库,使用-l来使用它。

相关问题