2017-09-25 15 views
4

부동 소수점의 절대 값을 표시하는 간단한 프로그램 fabs.c을 작성했습니다.GCC로 컴파일 할 때 fabs()에 -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

Gcc는 일부 내장 버전의 기능을 인라인합니다. '-fno-builtin-fabs'를 시도하십시오. –

+0

@MarcGlisse 고맙습니다. 인라인의 의미를 정확히 알지는 못하지만. – LinuxBabe

+0

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

답변

1

gcc가 일부 코드를 최적화하기 때문에. printf처럼 gcc는 fabs 건을 대신 할 수 있습니다. 확실히, 당신은 그렇게에서 GCC를 금지하는 -fno-builtin와 소스 코드를 컴파일 할 수

[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

일부 C 소스 파일을 컴파일 한 결과로 어셈블러 파일을 얻으려면 gcc -S -O -fverbose-asm을 사용하는 것이 좋습니다. 그래서'gcc -Wall -S -O -fverbose-asm main.c'은 호출기 나 편집자와 함께 생성 된'main.s' 파일을 보게됩니다. –

3

를 수동 당신 있다고 경우 -lm과 연결되어야하며 -lm으로 연결해야합니다. 이 경우 코드가 매우 간단하고 컴파일러는 시스템을 인라인 할만큼 똑똑합니다 (시스템에 항상 gcc가 내장되어 있기 때문에). 아마도 어떤 경우에는 그럴 수 없을 것입니다. 부동 소수점 함수 내장 함수 중 일부는 흔히 인라인 될 수없는 경우 라이브러리 함수로 폴백합니다 (fabs이 아닌 다른 많은 함수).

매뉴얼에서는 "do X"라고 말하기가 쉽기 때문에 "C가 아니라 A, B를 할 경우, 말할 필요가 없을 수도 있기 때문에 모든 경우에 꼭 필요한 것은 아닙니다. 우리가 D를 추가하고 B가 아마도 바뀔 것이기 때문에 다음 버전에서 매뉴얼을 읽으십시오, 우리는 (우리가 마음이 바뀌지 않는 한) A를 결코 바꿀 수 없을 것입니다. "

-lm으로 링크하면 프로그램이 합리적으로 가까운 미래에 가장 합리적인 시스템에서 작동 할 수 있습니다. 이 특정 시점에 한 특정 컴퓨터에서이 특정 코드를 사용하는 것이 꼭 필요한 것은 아니지만 이번에는 특정 옵션으로 컴파일해야합니다.