2011-08-22 3 views
4

GCC 4.4.5가 설치된 gentoo linux에 있습니다. 컴파일하고 오류없이 해당 프로그램을 연결할 수 있습니다. gcc main.c -o main./main 명령이 결과를 올바르게 반환합니다.여러개의 C 소스 파일을 연결하십시오.

[main.c] 
#include <math.h> 
#include <stdio.h> 
int main(void) 
{ 
    double c = ceil(2.5); 
    printf("The ceil of 2.5 is %f\n", c); 
    return 0; 
} 

하지만 다른 소스 파일에 CEIL의 invokation을 넣을 때 문제가 발생합니다. 명령을 사용하여

[calc.h] 
#ifndef _CALC_H_ 
#define _CALC_H_ 
double myceil(double n); 
#endif 

[calc.c] 
#include <math.h> 
#include "calc.h" 
double myceil(double n) 
{ 
    return ceil(n); 
} 

[main1.c] 
#include <stdio.h> 
#include "calc.h" 
int main(void) 
{ 
    double c = myceil(2.5); 
    printf("The ceil of 2.5 is %f\n", c); 
    return 0; 
} 

GCC calc.c main1.c -o 메인 1 같은 오류가 발생합니다

/tmp/cc6GhJvZ.o: In function `myceil': 
calc.c:(.text+0x19): undefined reference to `ceil' 
collect2: ld returned 1 exit status 

는 왜 짜증나는 오류가 "정의되지 않은 참조는"후자의 경우에 일어 났습니까? 그리고 오류가 라이브러리 -lm을 추가하여 제거 될 수 있다는 것을 알고 있습니다. 그러나 gcc가 후자의 경우 오류를 던지는 이유를 알고 싶습니다.

+0

이 오류는 osx 또는 RHEL 6 ... –

+0

@ Foo에 표시되지 않습니다. 최근에 Vmware Workstation 7.0.0에서 rhel-workstation-6.0-i386-dvd.iso를 설치했지만 오류가 여전히 있습니다. – machinarium

+0

ooh x64 서버 버전 –

답변

5

내 생각 calc.c 컴파일시 n가 알려져 있지 않기 때문에 ceil(n)가 일정하지 않은 반면 GCC는 상수로 최적화 ceil(2.5) 것을이며 함수를 참조 할 필요가있다. 어셈블리 출력 (gcc -S)을 보면이를 확인할 수 있습니다.

업데이트 :

.LC1: .string "%f\n" // [snip] main: // [snip] fldl .LC0 fstpl 4(%esp) movl $.LC1, (%esp) call printf // [snip] .LC0: .long 0 .long 1074266112 

가 여기에 우리가 printfdouble 일정으로 호출되는 참조 :
가 여기에 첫 번째 예와 유사한 무언가를 준 x86에서 어떤 GCC 4.2.1입니다.
myceil: 
    // [snip] 
    fldl -8(%ebp) 
    fstpl (%esp) 
    call ceil 
    // [snip] 

가 여기에 우리가 ceil가 참조되는 참조 :

는 이제 두 번째 예와 비슷한 일을합니다.

그래. 전화가 -lm없이 작동하는 상수로 최적화되고 있다고 말하고 싶습니다.

+0

'gcc -S'를 구체적으로 사용하는 방법이나 튜토리얼을 가르쳐 주시겠습니까? 감사. – machinarium

+0

예제 사용법 :'gcc -S foo.c'. 'foo.s'라는 파일을 출력합니다. 물론 플랫폼의 어셈블리 언어에 대한 지식도 많은 도움이 될 것입니다. – asveikau

+0

대단히 감사합니다. 문제는 정확히 당신이 말하는 것입니다. 나는'ceil (2.5)'를'ceil (x)'로 대체 할 때 x의 값이 2.5 일 때, 참조 에러는 나의 후자의 경우처럼 발생한다. – machinarium

0

먼저 main.c를 main.o로 컴파일하고 calc.c를 calc.o로 컴파일 한 다음 링크하면됩니까? 그게 보통 내가 기대했던 것입니다 (하나의 명령 행에서 여러개의 C 파일을 컴파일하는 것보다는 오브젝트 파일을 링크하는 것입니다).

+0

을 사용했습니다. 회신 해 주셔서 감사합니다. 나는'gcc -c calc.c''gcc -c main1.c'와'gcc -o main1 calc.o main1.o' 명령을 사용하지만, 여전히 같은 오류가 발생합니다. – machinarium

2

gcc는 built-in functions이고 ceil은 그 중 하나입니다. OSX의 제 버전에서 gcc는 두 가지 경우 모두에 내장 된 ceil을 사용하므로 -lm은 필요하지 않습니다. 외관상으로는 Gentoo 컴파일러는 다르게 동작하며 경우에 따라 내장형 ceil 만 사용합니다. -fno-builtin으로 컴파일하려고하면 두 컴파일 모두에 -lm을 사용해야합니다.

+0

감사합니다. – machinarium

+0

고맙습니다. @mu. 'gcc -fnobuilt-in main.c -o main'을 사용하면 참조 오류가 발생합니다. 내 젠투에서 기본 제공 함수는 상수 매개 변수 (예 : 내 이전의 경우 2.5. – machinarium

+0

@ machinarium : 멋지 네요. 최적화 된 것 같아요.하지만 혼란스러운 행동을 일으킬 수 있기 때문에 내장 함수에 대해 언급하고 싶습니다. 컴파일러의 구성에서 여러 파일 문제 일 수도 있습니다. –

관련 문제