#include<math.h>
#include<stdio.h>
int main(void)
{
int n=2;
printf("%f\n",pow(n, 3));
return 0;
}
위의 코드는 단순히 'gcc 파일명’으로는 리눅스 환경에서 컴파일이 안되더군요. 어줍짢은 영어실력으로 구글링을 해보니까 'gcc 파일명 -lm’으로 라이브러리를 지정해줘야한다고 하더군요.
여기서 몇가지 질문이 있습니다.
- 헤더파일 역시도 일종의 라이브러리인데, 왜 컴파일러는 헤더파일 선언 뿐만 아니라 굳이 이런 번거로운 과정을 요구하는 것인가요?
- 위의 코드에서 printf("%f\n",pow(n, 3))가 아니라 printf("%f\n",pow(2, 3))라고 적으니 -lm 옵션이 없이도 컴파일이 되었습니다. 변수가 아니라 상수를 적으니까 -lm 옵션이 필요없어졌는데 그 이유는 무엇인가요?
- 이러한 라이브러리 옵션은 어떻게 확인하는 것인가요? 예를들어서 math.h와 관련있는 라이브러리는 'm’이라는 사실을 알아내는 어떠한 규칙 같은게 존재하나요? 다른 헤더파일들의 경우도 구글링으로 헤더파일 하나하나 라이브러리 옵션을 알아보는 방법 밖에 없는 것인가요?
이를테면 "헤더파일 이름에서 확장자 h를 제거한게 라이브러리 옵션이다!!" 같은 규칙은 전혀 없나요?(이 규칙은 어디까지나 예로 든 것입니다)
그나마 관련있어 보이는게 헤더파일의 이니셜인데, 이렇게 따질 경우 이니셜이 중복되는 헤더파일도 많아서 이건 좀 아닌 것 같네요.
-
헤더파일에는 함수 선언만 되어있고 함수의 내용이 없습니다.
함수 내용은 미리 컴파일 된 상태로 어딘가(예: /usr/lib/libm.a 또는 /usr/lib/x86_64-linux-gnu/libm.a)에 저장됩니다.
-
컴파일러 최적화일 가능성이 높습니다. 어차피 실행될 때 마다 결과값이 같다면 gcc가 미리 계산해서 결과값만 프로그램에 저장해두는거죠. 그래서 pow()함수의 내용이 필요없어서 libm.a 파일을 요구하지 않는 겁니다.
-
터미널에서
man 3 pow
라고 쳐보시면
[quote:176cc8p4]
POW(3) Linux Programmer’s Manual POW(3)
NAME
pow, powf, powl - power functions
SYNOPSIS
#include <math.h>
double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);
Link with -lm.
[/quote:176cc8p4]
라고 친절하게 알려줍니다.
1번은 반대로 생각해보시면 이유를 알게됩니다.
수많은 헤더 파일과 라이브러리가 있는데 프로그래머가 어떤 걸 사용하는지 컴퓨터는 알지 못합니다.
2번은 최적화일 것 같고
3번은 일일이 찾아봐야 합니다.
gcc 뿐만이 아니라 터보씨, MSVC 등… 모든 C컴파일러가 그렇습니다.
참고로 python, ruby 같은 동적 언어도 라이브러리를 import 해줘야 합니다. 그건 어쩔 수 없는 부분입니다.
프로그래머가 뭘 사용할지 컴퓨터는 모르기 때문입니다.
참고로 autotools, pkg-config 라는 물건이 있습니다. 이런 물건들이 님께서 불편해하시는 부분을 대부분 해결해줄 겁니다. 이런 도구들을 사용하시면 매우 편리하게 컴파일할 수 있습니다.
man에 대해 좀 더 알고, 평소에 꼬박꼬박 확인하는 습관을 길러야겠네요…
많은 도움이 되었습니다.
몇분께서 자세히 설명해주셨는데요…
불친절한 사람이라면 RTFM 이렇게 넉자 답변 쓰는 경우도 있어요. 이 사이트는 안 그런 것 같은데 다른사이트에서요…
그럴땐 Read The Fine Manual 매뉴얼을 읽으시오라고 이해하시면 됩니다.
참고하셔요. ![하하 :)]()