当我编写一个使用math.h
库中函数的程序时,为什么我必须明确链接到libm
,即使它们是C标准库的一部分?
例如,当我想使用sin()
函数时我需要#include <math.h>
,但我还需要将-lm
传递给GCC。但对于标准库中的任何其他库,我不必这样做。为什么不同?
答案 0 :(得分:16)
在过去,链接器很慢,并且将大部分未使用的数学代码与其他代码分开,这使得编译过程变得更快。今天的差异并不大,因此您可以将-lm
选项添加到默认编译器配置中。
请注意,标头<math.h>
(或任何其他标头)不包含代码。它包含有关代码的信息,特别是如何来调用函数。代码本身在库中。我的意思是,你的程序不使用“<math.h>
库”,它使用数学库并使用<math.h>
标题中声明的原型。
答案 1 :(得分:5)
这与您在大多数实现中明确链接到libpthread
的原因相同。当一些新的和可怕的东西被添加到标准库时,它通常首先被实现为一个单独的附加库,它覆盖旧标准库实现中的一些符号,其版本符合新的要求,同时还添加了许多新界面。如果某些历史实现在printf
中具有用于浮点打印的libm
的单独版本,并且主libc
中的“轻”版本缺少浮点,我不会感到惊讶。如果我没记错的话,实际上会在ISO C基本原理文档中提到并鼓励这种实现。
当然,从长远来看,将标准库分离出来会带来更多问题而不是好处。最糟糕的部分可能是动态链接程序的加载时间和内存使用量增加。
答案 2 :(得分:2)
实际上,对于大多数数学函数,通常不需要链接libm的原因是编译器会内联这些函数。如果不是这种情况,您的程序将无法链接到平台上。