2017-09-25 103 views
4

我寫了一個簡單的程序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 –

回答

1

因爲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' –

3

如果手動說你應該鏈接-lm,那麼你應該鏈接-lm。在這種情況下,你的代碼非常簡單,而且編譯器足夠聰明,可以將它內聯(因爲你的系統總是使用內置的gcc)。也許在某些情況下它將無法使用。一些浮點函數內置函數如果不能被簡單內聯(不是fabs,而是許多其他函數),則會回退到庫函數。

手冊經常告訴你做所有情況下不必要的事情,因爲說「做X」更容易,而不是說「如果你做A,B,但不是C,你可能不需要做X,但請閱讀下一版本的手冊,因爲我們將添加D和B可能會改變,我們永遠不會改變A(除非我們改變主意)「。

通過與-lm鏈接,確保您的程序可以在合理可預見的將來在最合理的系統上運行。儘管在特定的時間點上某個特定機器上並不是絕對必要的,但使用此次特定的選項編譯此特定代碼。

相關問題