为什么我必须明确地链接libm?

可能重复:
为什么必须在C中链接数学库?

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

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

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


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

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

当然,从长远来看,将标准库分离出来会带来更多问题而不是收益。 最糟糕的部分可能是动态链接程序的加载时间和内存使用量增加。

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