为什么需要一个明确的`-lm`编译器选项
可能重复:
gcc:为什么链接数学库需要-lm标志?
一般来说,除了包含头文件math.h
之外,为了使用任何数学函数,您必须使用链接器选项-lm进行链接。 -l
这里将指代用于搜索特定库libm.o
的链接器选项。
我的问题是
为什么GCC默认不包含此库? 是因为库大量使用数学协处理器,它需要添加额外的代码来初始化浮点初始化(我可能在这里使用了错误的术语)?
注意
我刚刚查看了http://stackoverflow.com链接中提到的所有答案。 这对我来说没什么意义。 归因于三个基本原因
- 保证标准库可用。 链接其他posix库(如pthread)明确有意义,但为什么我们必须为标准库做一个显式链接。 即使是历史原因也不是很清楚。
- 为什么libm与libc分开?
- 为什么我们仍然在最近的gcc编译器中inheritance这些行为? 它有什么简单性? 这是我测试的,没有libm和libm。 没有libm的那个,我已经写了我自己的Pow版本
这是一个例子
abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c "echo {} && echo "-----------------" && cat {}" Test_withlibm.c ----------------- #include #include int main() { int i=20; double output1=pow(2.618033988749895,i); return 0; } Test_withoutlibm.c ----------------- #include #include 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
它适用于不可能或不需要浮点数学的系统(主要是嵌入式)。 这确实是历史性的,但不要忘记gcc
和大多数其他C编译器是在386SX被认为是高性能处理器的时代编写的。
举个例子,当我还在嵌入式计算领域工作时,我们使用标准编译器(Microsoft和Borland)为我们的处理器生成代码(Z80,80186和68030)。 如果编译器默认链接到数学库,那么我们就会遇到麻烦,因为我们的系统都没有浮点function甚至不需要它。
确实,30年之后它似乎很愚蠢,但当时的原因是合理的。
您可能需要许多库,而libm
只是其中之一。
对于其中的每一个,您可能会问为什么默认情况下不包含它。
也许libm
比其他人更有用,但仍然,C更喜欢保持简单 – 你想要一个库,使用-l
来使用它。
历史原因
libc
和libm
分离的原因是你必须在命令行上指定-lm
是历史原因,因为libm
编译器也使用了libm
。