编译时不需要链接C libm.a

编译时不需要链接C libm.a,c,gcc,C,Gcc,我试图编译一个包含的源文件。 但是,我成功地创建了一个可执行文件,没有链接到libm.a,就没有错误 我键入的命令是gcc-Wall filename.c-o executablename 我被告知链接到外部库(即/libc.a以外的库) 发生什么事了 #include <math.h> #include <stdio.h> int main(void) { double x = sqrt(2.0); printf ("The sqrt of 2 is:

我试图编译一个包含
的源文件。 但是,我成功地创建了一个可执行文件,没有链接到
libm.a
,就没有错误

我键入的命令是
gcc-Wall filename.c-o executablename

我被告知链接到外部库(即/libc.a以外的库)

发生什么事了

#include <math.h>
#include <stdio.h>

int main(void)
{
    double x = sqrt(2.0);
    printf ("The sqrt of 2 is: %f\n", x);
    return 0;
}
#包括
#包括
内部主(空)
{
双x=sqrt(2.0);
printf(“2的sqrt为:%f\n”,x);
返回0;
}

您调用的数学函数由编译器内置函数实现。如果要查看错误消息,请尝试以下操作:

gcc-fno内置-Wall filename.c-o executablename
例如,在我的平台(Ubuntu 14.04.3 LTS)上,我收到以下错误消息:

$cat x.c
#包括
#包括
内部主(空)
{
双x=sqrt(2.0);
printf(“2的sqrt为:%f\n”,x);
返回0;
}
$gcc-fno内置x.c
/tmp/ccpjG2Pb.o:在函数“main”中:
x、 c:(.text+0x1c):对“sqrt”的未定义引用
collect2:错误:ld返回了1个退出状态

一些编译器,比如OSX上当前的
clang
(伪装成
gcc
),不需要告诉它们将可执行文件与数学库链接起来

OSX上的
clang
会将您的可执行文件链接到
/usr/lib/libSystem.B.dylib
(对于一个简单的程序,仅此而已)。此库依次使用库
/usr/lib/system/libsystem_m.dylib
,这是一个数学库。

与许多其他函数一样,
中的函数(或首选的
)也是C库的一部分。如果C库中的所有函数实际上都链接到一个库中,或者分别链接到多个块中,则这取决于平台

在古代,库的大小是链接时间的一个问题,库越大,链接具有许多未解析符号的可执行文件所需的时间就越长。这些时代早已过去,但在某些平台上,将libc.a和libm.a分离为
libc.a和
libm.a的做法盛行


如果您的平台不需要使用
-lm
进行链接,那么它应该有一个虚拟(空)版本的
libm.a
,只要您的链接命令行上有该版本就没有错误。例如,位于Alpine Linux基础上的C库就是这样。

哪个平台?例如,这在MacOSX上是正常的。另外,您是如何使用
中的函数的?如果这些值可以由编译器计算,那么它们可能是,并且不需要在可执行文件中调用函数,因此链接不会注意到您没有链接到数学库。将
-v
添加到您的命令行,您将立即看到发生了什么。这是您正在使用的确切代码的复制粘贴吗?因为
sqrt()ago@M.M哪只虫子?不必
-lm
?或者
sqrt()
不接受两个参数;-)不,即使使用-fno内置和-Wall标志,它仍然可以编译,没有错误。请将您的程序缩减为最短的程序,以演示您的问题。请将该程序复制粘贴到您的问题中。有关更多信息,请参阅。我可以使用选项
-fno builtin
重现上述错误。没有它,即使我没有为gcc指定
-lm
选项,程序也会编译。@jdhao-这正是我在回答中描述的行为。如果我在cygwin@hemel检查根据编译的可执行文件链接的库。在普通Unix系统上,这将通过
ldd a.out
完成。您可能会在那里发现
libm
。当您使用数学函数时,与
-lm
链接从来都没有错。。。由于这与链接而不是编译有关,我认为
-Wall
在报告方面不会有多大作用(因为它主要处理代码问题,而不是链接问题)独立数学库的另一个历史原因是,一些机器没有硬件浮点,因此需要软件仿真库,而另一些机器有硬件浮点,不需要仿真。如果这两个库是分开的,那么管理起来就更容易了。这是否意味着libc.a可能支持libm.a的功能?@hemel
libc
(或系统选择的任何名称)可以包含所有内容,包括数学、加密、网络和图形渲染例程(如果在特定平台上有意义)。@hemel,我想你的意思是它是否可以包含
中的函数?对如何链接不是C标准的一部分。