为什么必须用C语言链接数学库?
如果我在C程序中包含为什么必须用C语言链接数学库?,c,compilation,math.h,C,Compilation,Math.h,如果我在C程序中包含或,我在编译时不必链接它们,但我必须使用带有gcc的-lm链接到,例如: gcc test.c -o test -lm 这是什么原因?为什么我必须显式链接数学库而不是其他库?stdio是标准C库的一部分,默认情况下,gcc将链接到该库 数学函数实现位于一个单独的libm文件中,默认情况下该文件未链接到该文件,因此必须将其指定为-lm。顺便说一下,这些头文件和库文件之间没有关系 我觉得这有点武断。您必须在某处画一条线(哪些库是默认库,哪些需要指定) 它让你有机会用一个具有相同
或
,我在编译时不必链接它们,但我必须使用带有gcc的-lm
链接到
,例如:
gcc test.c -o test -lm
这是什么原因?为什么我必须显式链接数学库而不是其他库?stdio是标准C库的一部分,默认情况下,gcc将链接到该库
数学函数实现位于一个单独的libm文件中,默认情况下该文件未链接到该文件,因此必须将其指定为-lm。顺便说一下,这些头文件和库文件之间没有关系 我觉得这有点武断。您必须在某处画一条线(哪些库是默认库,哪些需要指定) 它让你有机会用一个具有相同功能的不同的替换它,但我认为这样做并不常见
编辑:(来自我自己的评论):我认为gcc这样做是为了保持与原始cc的向后兼容性。我猜cc为什么会这样做是因为构建时间——cc是为功率远低于现在的机器编写的。很多程序都没有浮点运算,它们可能会将所有不常用的库都从默认值中删除。我猜UNIX操作系统的构建时间和随之而来的工具是驱动力。我想这是一种让根本不使用它的应用程序性能稍好一点的方法。这是我的想法 x86操作系统(我想象其他操作系统)需要在上下文开关上存储FPU状态。然而,大多数操作系统只是在应用程序首次尝试使用FPU后才保存/恢复此状态 除此之外,数学库中可能还有一些基本代码,在加载库时,这些代码会将FPU设置为正常的基本状态 因此,如果您根本不链接任何数学代码,这一切都不会发生,因此操作系统根本不必保存/恢复任何FPU状态,从而使上下文切换稍微更有效 不过只是猜测而已 编辑:对于一些评论,相同的基本前提仍然适用于非FPU情况(前提是要使没有使用libm的应用程序性能稍好一些) 例如,如果有一个软FPU,它在C的早期是likley,那么将libm分离可以防止大量大型(如果使用它,则速度较慢)代码被不必要地链接进来
此外,如果只有静态链接可用,那么类似的论点也适用,即它可以降低可执行文件的大小和编译时间。中详细讨论了链接到外部库的问题。如果库是标准库(如stdio)的成员,则无需指定编译器(实际上是链接器)来链接它们 编辑:在阅读了其他一些答案和评论之后,我认为它链接到的和libm参考都有很多关于为什么两者是分开的 请注意,“libm.a”(数学库)中的许多函数在“math.h”中定义,但在libc.a中不存在。有些是,这可能会让人困惑,但经验法则是——C库包含ANSI规定必须存在的函数,因此如果只使用ANSI函数,则不需要-lm。相反,`libm.a'包含更多函数,并支持其他功能,如matherr回调和在发生FP错误时遵守若干替代行为标准。有关更多详细信息,请参见libm部分
stdlib.h
和stdio.h
中的函数在libc.so
中有实现(或libc.a
用于静态链接),默认情况下链接到可执行文件中(好像指定了-lc
)。可以指示GCC使用-nostlib
或-nodefaultlibs
选项避免此自动链接
math.h
中的数学函数在libm.so
中有实现(或libm.a
用于静态链接),默认情况下,libm
不链接。libm/libc
拆分有历史原因,但没有一个很有说服力
有趣的是,C++运行时<代码> LBSTDC++< /COD>需要代码> LBM< /Cuff>,所以如果用GCC编译一个C++程序(<代码> G++<代码> >,你将自动获得stdlib.h
,stdio.h
是头文件。为了方便起见,您可以将其包括在内。它们仅预测在适当的库中链接时可用的符号。这些实现在库文件中,这是函数真正存在的地方
包括math.h
只是访问所有数学函数的第一步
此外,如果不使用libm
的函数,即使您执行了#include
操作,也不必链接到libm
,这对于编译器来说只是一个关于符号的信息性步骤
stdlib.h
,stdio.h
指的是libc
中提供的函数,这些函数总是链接在一起,这样用户就不必自己做了。请记住,C是一种古老的语言,fpu是一种相对较新的现象。我第一次在8位处理器上看到C,在那里,即使是32位整数运算也需要大量的工作。许多实现甚至没有可用的浮点数学库
即使在最初的68000台机器上(Mac、Atari ST、Amiga),浮点协处理器通常也是昂贵的附加组件
要完成所有的浮点运算,您需要一个相当大的库。数学会很慢。所以你很少用花车。你试过了
ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o
/usr/lib/crti.o /usr/libgcc-lib /i686/3.3.1/crtbegin.o
-L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc
-lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o