2012-09-17 7 views
1

저는 C++을 배우고 있습니다. g로 컴파일 ++ 버전 3.2.3, "g ++ hworld.cpp"잘 컴파일,하지만 우리는 "sqrtfoo"와 SQRT을 대체한다면 컴파일러는 sqrtfoo 함수로 사용할 수 없습니다 말을C++에서 sqrt() 함수를 사용하기 위해 무엇인가를 포함시켜야하는 이유는 무엇입니까?

double sqrt(double); 
int main(){ 
    double x = sqrt(1515.15); 
    return 0; 
} 

. 나는 cmath를 포함해야한다고 생각했지만, 그렇지 않습니까? 누군가 내 프로그램이 어떤 것을 포함하기 전에 접근 할 수 있는지 설명해 주시겠습니까? 비교를 위해 gcc는 "sqrt '에 대한 정의되지 않은 참조를 말하는 것을 허용하지 않습니다." 고맙습니다.

+0

GCC 3.2 .... 대기, * * *? – Xeo

답변

2

기존 답변에서 설명한대로 double sort(double)은 함수가 있음을 컴파일러에서 알 수있는 프로토 타입을 제공합니다.

그러나 GCC에서는 작동하지 않는다고 언급했습니다. C 또는 C++ 프로그램을 빌드하면 소스 코드가 오브젝트 형식으로 컴파일됩니다. 그런 다음 오브젝트 파일을 링크하여 실행 파일을 만듭니다.

는 동작에서 볼이 (-c) 소스 파일에서는 hello.c를 컴파일하기 위해 GCC를 알려줍니다

gcc -c hello.c 

시도합니다. hello.c가 있고 오류가 없다고 가정하면 hello.o가 현재 디렉토리에서 발견됩니다. 지금 시도하십시오

이렇게하면 GCC가 hello.o를 적절한 시스템 라이브러리에 연결하고 "hello"라는 출력 파일을 생성합니다. 에서는 hello.c가 수학 함수를 사용하는 경우, 당신은 또한 수학 라이브러리에 링크해야합니다 :

gcc -o hello hello.o -lm 

"-l"추가 라이브러리를 포함하는 GCC를 얘기하는 데 사용되는 (C 라이브러리 "libc의"기본 이상) . "m"은 sqrt을 포함하는 수학 라이브러리 인 "libm"을 나타냅니다. 프로그램이 하나의 소스 파일을 사용하는 경우는 하나의 명령으로 컴파일 및 링크하는 암시 적으로 GCC를 요청하는 것이 일반적이다 :

gcc -o hello hello.c -lm 

을 이제 귀하의 질문에. GCC는 수학 라이브러리에서 링크하도록 요청하지 않았기 때문에 위의 코드를 컴파일하지 않습니다. 하지만 g ++은 괜찮습니다. 이미 스택 오버플로에 similar question이 있습니다. 그 허용 대답,

에 따르면 C++ 런타임 된 libstdC++가 필요하기 libm의, 그래서 당신은 GCC와 (g를 ++)는 C++ 프로그램을 컴파일하는 경우, 당신은 자동으로 libm의은에 연결 얻을 것이다.

"libstdC++"는 C++ 언어 런타임 라이브러리이므로 기본적으로 g ++에 포함되어 있습니다. libm에 의존하기 때문에 링커는 최종 바이너리 프로그램을 생성하는 동안 libm을 자동으로로드합니다.

+0

매우 자세한 설명에 감사드립니다. – user1676558

3

코드에 sqrt의 프로토 타입이 이미 있기 때문에 cmath을 포함 할 필요가 없습니다. 첫 번째 줄.

+0

좋아요, 저는 함수 프로토 타입보다 include 문에서 더 많은 일이 벌어지고 있다고 생각했습니다. 나는 '#include '이 실제로 이전에 액세스 할 수 없었던 몇 가지 추가 코드를 포함한다고 생각했지만, 분명히 이미 선언되어 있다면 이미 이미 어딘가에 있으며 액세스 할 수 있습니까? gcc로 컴파일 할 때 이것이 왜 비슷하게 작동하지 않는지 궁금합니다. – user1676558

+0

@ user1676558 : 대부분 gcc의 문제는 수학 라이브러리에 연결하지 않았다는 것입니다. '-lm'을 명령 행에 추가 해보십시오. –

+0

아, 네, 이제 컴파일됩니다. 흥미 롭군요, 고마워요. – user1676558

1

헤더 파일은 선언 (서명) 만 포함하고 첫 번째 행 (프로토 타입 : double sqrt(double))에 헤더 파일을 포함 시켰습니다.

컴파일러는이 함수가 정의 된 어딘가에 명시 했으므로이 컴파일러를 컴파일합니다. 컴파일 후에 발생하는 단계는 실제로 해당 함수 정의를 찾습니다. linking이라고하며 해당 단계에서 링커는 해당 정의를 조회합니다. sqrtfoo의 경우에는 아무 것도 찾을 수 없지만 sqrt의 경우 일부 표준 라이브러리에서 발견됩니다 (자세한 내용은 여기에서 알지 못합니다).

+0

아, 나는 그런 식으로 작동하는 헤더 파일을 몰랐다. 감사. – user1676558