为什么fabs()在编译GCC时不需要-lm选项

问题描述:

我写了一个简单的程序fabs.c来显示浮点数的绝对值。为什么fabs()在编译GCC时不需要-lm选项

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

int main(void) 
{ 
    float f; 

    printf("Enter a floating-point number: "); 
    scanf("%f", &f); 

    printf("Its absolute value is %f.\n", fabs(f)); 
    return 0; 
} 

晶圆厂()函数需要包括math.h头文件,但我不-lm选项编译成功。

gcc fabs.c -o fabs 

即使man fabslink with -lm。但我不知道为什么我可以在没有-lm的情况下成功编译它。

+7

海湾合作委员会内联函数的一些内置版本。尝试'-fno-builtin-fabs'。 –

+0

@MarcGlisse谢谢,虽然我不确切知道内联的含义。 – LinuxBabe

+0

https://en.wikipedia.org/wiki/Inline_expansion –

因为gcc会优化你的一些代码。像printf,gcc可以代替fabs调用。可以肯定,你可以用​​编译源代码,这样做禁止GCC:

[email protected]:/tmp/toto$ gcc -fno-builtin main.c 
/tmp/cc5fWozq.o: In function `main': 
main.c:(.text+0x37): undefined reference to `fabs' 
collect2: error: ld returned 1 exit status 

您还可以使用nm列出您的可执行文件的符号:

[email protected]:/tmp/toto$ nm ./a.out 
0000000000600a18 B __bss_start 
0000000000600a18 b completed.6661 
0000000000600a08 D __data_start 
0000000000600a08 W data_start 
00000000004004b0 t deregister_tm_clones 
0000000000400530 t __do_global_dtors_aux 
00000000006007e8 t __do_global_dtors_aux_fini_array_entry 
0000000000600a10 D __dso_handle 
00000000006007f8 d _DYNAMIC 
0000000000600a18 D _edata 
0000000000600a20 B _end 
0000000000400644 T _fini 
0000000000400550 t frame_dummy 
00000000006007e0 t __frame_dummy_init_array_entry 
00000000004007d8 r __FRAME_END__ 
00000000006009d0 d _GLOBAL_OFFSET_TABLE_ 
       w __gmon_start__ 
0000000000400408 T _init 
00000000006007e8 t __init_array_end 
00000000006007e0 t __init_array_start 
0000000000400650 R _IO_stdin_used 
       U [email protected]@GLIBC_2.7 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
00000000006007f0 d __JCR_END__ 
00000000006007f0 d __JCR_LIST__ 
       w _Jv_RegisterClasses 
0000000000400640 T __libc_csu_fini 
00000000004005d0 T __libc_csu_init 
       U [email protected]@GLIBC_2.2.5 
0000000000400576 T main 
       U [email protected]@GLIBC_2.2.5 
00000000004004f0 t register_tm_clones 
0000000000400480 T _start 
0000000000600a18 D __TMC_END__ 
+1

我会建议使用'GCC -S -O -fverbose-asm'得到汇编文件,一些C源文件编译的结果。因此'gcc -Wall -S -O -fverbose-asm main.c'然后用寻呼机或编辑器查看生成的'main.s' –

如果手动说你应该链接-lm,那么你应该链接-lm。在这种情况下,你的代码非常简单,而且编译器足够聪明,可以将它内联(因为你的系统总是使用内置的gcc)。也许在某些情况下它将无法使用。一些浮点函数内置函数如果不能被简单内联(不是fabs,而是许多其他函数),则会回退到库函数。

手册经常告诉你做所有情况下不必要的事情,因为说“做X”更容易,而不是说“如果你做A,B,但不是C,你可能不需要做X,但请阅读下一版本的手册,因为我们将添加D和B可能会改变,我们永远不会改变A(除非我们改变主意)“。

通过与-lm链接,确保您的程序可以在合理可预见的将来在最合理的系统上运行。尽管在特定的时间点上某个特定机器上并不是绝对必要的,但使用此次特定的选项编译此特定代码。