【问题标题】:Why do I have to explicitly link with libm? [duplicate]为什么我必须显式链接 libm? [复制]
【发布时间】:2011-07-22 02:52:54
【问题描述】:

可能重复:
Why do you have to link the math library in C?

当我编写一个使用 math.h 库中的函数的程序时,为什么我必须显式链接到 libm,即使它们是 C 标准库的一部分?

例如,当我想使用sin() 函数时,我需要#include <math.h>,但我还需要将-lm 传递给GCC。但是对于标准库中的任何其他库,我不必这样做。为什么会有差异?

【问题讨论】:

    标签: c gcc


    【解决方案1】:

    在过去,链接器很慢,将大部分未使用的数学代码与其他代码分开可以加快编译过程。今天的差别不是很大,因此您可以将-lm 选项添加到您的默认编译器配置中。


    请注意,标头 <math.h>(或任何其他标头)不包含代码。它包含有关代码的信息,特别是如何调用函数。代码本身在库中。我的意思是,您的程序不使用 "<math.h> 库",它使用数学库并使用在 <math.h> 标头中声明的原型。

    【讨论】:

      【解决方案2】:

      这与在大多数实现中必须显式链接到 libpthread 的原因相同。当标准库中添加了一些新的和可怕的东西时,它通常首先被实现为一个单独的附加库,它用符合新要求的版本覆盖旧标准库实现中的一些符号,同时还添加了很多新的接口。如果某些历史实现在libm 中有单独的printf 版本用于浮点打印,我不会感到惊讶,而主libc 中的“轻”版本缺少浮点。如果我没记错的话,ISO C 基本原理文档中实际上提到并鼓励了这种实现。

      当然,从长远来看,像这样将标准库分开会导致更多的问题而不是好处。最糟糕的部分可能是动态链接程序的加载时间和内存使用量增加。

      【讨论】:

        【解决方案3】:

        实际上,对于大多数数学函数,您通常不需要链接到 libm 的原因是这些函数是由您的编译器内联的。如果不是这种情况,您的程序将无法在平台上链接。

        【讨论】:

        • libm 的大部分内容是不可能内联的,除非您的内联函数限制为几 KB,或者您启用了像 -ffast-math 这样的 hack,它允许编译器生成不正确但快速的代码。
        • 嗯,在 x86 上,正弦和余弦是在 FPU 内部实现的,并且可以通过一条指令访问,因此内联在这里很有意义。仅使用 sin() 的程序将不需要在 x86 上链接到 libm,从而隐藏缺少的库引用。
        • 你确定FPUsin指令可以直接实现sin()吗?如果我没记错的话,首先需要一个重要的参数缩减步骤。
        • 好的,这是一个不好的例子,我很抱歉。 fabs() 在 x86 上更好。我最初的观点仍然成立:如果您使用的所有函数都是内联的,那么即使数学库没有链接,程序也会链接并正常工作,但是由于显而易见的原因,这不是可移植的。
        • @SimonRichter 我们当中年纪较大的人还记得 x86 处理器没有嵌入式 FPU 的时代。 AFAIK,第一个带有嵌入式 FPU 的是 i486,甚至那个有一个没有 FPU 的残缺版本(称为 i486SX)。另外,OP 没有明确要求 x86。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-15
        • 2018-07-13
        • 1970-01-01
        • 2020-02-26
        相关资源
        最近更新 更多