为什么需要显式的`-lm`编译器选项

时间:2012-04-29 11:12:41

标签: c gcc floating-point

  

可能重复:
  gcc: why the -lm flag is needed to link the math library?

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

我的问题是

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

注意

我刚刚查看了链接http://stackoverflow.com中提到的所有答案。这对我来说没什么意义。

有三个基本原因
  1. 保证标准库可用。链接其他posix库(如pthread)显然是有意义的,但为什么我们必须为标准库做一个显式链接。即使是历史原因也不是很清楚。
  2. 为什么libm与libc分开?
  3. 为什么我们仍然在最近的gcc编译器中继承这些行为?它有什么简单性?这是我测试的,没有libm和libm。没有libm的那个,我已经写了我自己的Pow版本
  4. 以下是示例

    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
    

3 个答案:

答案 0 :(得分:9)

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

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

确实,30年之后,这似乎很愚蠢,但当时原因是合理的。

答案 1 :(得分:1)

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

或许libm比其他人更有用,但C仍然希望保持简单 - 你想要一个库,使用-l来使用它。

答案 2 :(得分:1)

历史原因

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