简体   繁体   English

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

[英]Why fabs() doesn't require the -lm option when compiling with GCC

I have written a simple program fabs.c to display the absolute value of a floating point number. 我编写了一个简单的程序fabs.c来显示浮点数的绝对值。

#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;
}

fabs() function requires including the math.h header file, but I compiled successfully without -lm option. fabs()函数需要包含math.h头文件,但我在没有-lm选项的情况下成功编译。

  gcc fabs.c -o fabs

Even man fabs says link with -lm . 甚至man fabslink with -lm But I don't know why I can compile it successfully without -lm . 但我不知道为什么我可以在没有-lm情况下成功编译它。

If the manual says that you should link with -lm , then you should link with -lm . 如果手册说你应该用-lm链接,那么你应该用-lm链接。 In this case your code is simple enough and the compiler is smart enough to inline it (because your system always uses the gcc built-in). 在这种情况下,您的代码非常简单,并且编译器足够智能以内联它(因为您的系统始终使用内置的gcc)。 Maybe it won't be able to in some cases. 也许在某些情况下无法做到。 Some of the floating point function built-ins fall back to the library functions if they can't be trivially inlined (not fabs , but many others). 一些浮点函数内置函数可以回溯到库函数,如果它们不能简单地内联(不是fabs ,而是许多其他)。

Manuals often tell you to do things that aren't strictly necessary in all cases because it's easier to say "do X" than to say "if you do A, B, but not C, you can maybe not have to do X, but please read the manual in the next version because we will add D and B will probably change, we'll never change A (unless we change our mind)". 手册通常会告诉你做一些在所有情况下都不是绝对必要的事情,因为它更容易说“做X”而不是说“如果你做A,B,但不是C,你可能不需要做X,但是请阅读下一版本的手册,因为我们将添加D和B可能会改变,我们永远不会改变A(除非我们改变主意)“。

By linking with -lm you ensure that your program will work on most reasonable systems for a reasonably foreseeable future. 通过与-lm链接,您可以确保您的程序在合理可预见的未来可以在大多数合理的系统上运行。 Even though it's not strictly necessary on one particular machine at this particular point in time, with this particular code, compiled with the particular options you had this time. 即使在这个特定的时间点,在某个特定的机器上并不是绝对必要的,使用这个特定的代码,使用您这次使用的特定选项进行编译。

Because gcc will optimize some of your code. 因为gcc会优化你的一些代码。 Like printf , gcc can replace fabs calls. printf一样,gcc可以取代fabs电话。 To be sure, you can compile your source code with -fno-builtin to forbid gcc from doing so: 可以肯定的是,您可以使用-fno-builtin编译源代码以禁止gcc执行此操作:

yoones@laptop:/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

You can also use nm to list your executable symbols: 您还可以使用nm列出可执行符号:

yoones@laptop:/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 __isoc99_scanf@@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 __libc_start_main@@GLIBC_2.2.5
0000000000400576 T main
                 U printf@@GLIBC_2.2.5
00000000004004f0 t register_tm_clones
0000000000400480 T _start
0000000000600a18 D __TMC_END__

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM