2014-09-02 7 views
0

실제로 여러 파일로 컴파일하고있었습니다. 파일은 다음과 같습니다다른 c 파일의 함수 호출

main.c 파일 ->

#include <stdio.h> 
void foo3(void) 
{ 
     printf("INSIDE foo3 function\n"); 
} 

int main() 
{ 
     foo1(); 
     foo2(); 
     foo3(); 
} 

파일 1.C ->

#include <stdio.h> 
void foo1(void) 
{ 
     printf("INSIDE foo1 function\n"); 
} 

파일 2.C ->

#include <stdio.h> 
void foo2(void) 
{ 
     printf("INSIDE foo2 function\n"); 
} 

다음과 같이 gcc를 사용하여 컴파일했습니다. ->

gcc 1.c 2.c main.c -o main 

다음은 출력했다 ->

INSIDE foo1 function 
INSIDE foo2 function 
INSIDE foo3 function 

내 의심의 여지가 그들이 main.c에 선언되지 않은 경우 main() foo1()foo2()를 호출 할 수있는 방법입니다. 하지만 지금과 같이 (main()foo3()의 정의를 작성) 다음과 같이 내가 main.c를 변경하는 경우 :

편집을 main.c를 ->

#include <stdio.h> 
int main() 
{ 
     foo1(); 
     foo2(); 
     foo3(); 
} 

void foo3(void) 
{ 
     printf("INSIDE foo3 function\n"); 
} 

다음 나는이 오류가 컴파일하는 경우 :
main.c:9:6: warning: conflicting types for ‘foo3’ [enabled by default] 
void foo3(void) 
    ^
main.c:6:2: note: previous implicit declaration of ‘foo3’ was here 
    foo3(); 
^

왜이 오류가 foo1()foo2()의 경우 이전에 표시되지 않았습니다. 미리 감사드립니다.

답변

1

My doubt is how could main() call foo1() and foo2() when they are not declared in main.c

int 결과를 제공에 GCC 컴파일러 선언되지 않은 기능을 허용 이전 ANSI C (일명 C89 등) 언어, 기본값 및 기본값 때문에.

예를 들어 다음과 같이 컴파일러를 호출하십시오.

gcc -std=c99 -Wall -g -c main.c 

또는

gcc -std=c99 -Wall -g 1.c 2.c main.c -o main 

을 (한 번에 모든 파일을 컴파일 할 경우) 사용 gcc -flto 대신 gcclink time interprocedural optimizations를 요청할 수있는 최근GCC, 예를 들어, GCC 4.9 (2014 년 9 월)

이렇게하면 모든 기능을 선언해야하는 C99 준수 소스 코드가 필요합니다. -Wall은 (거의) 모든 경고를 요구합니다. -g 옵션은 디버그 가능한 개체 코드 (또는 모든 파일을 한 번에 컴파일하는 마지막 명령에 대한 실행 파일)를 생성합니다. 귀하에

은 (main 내부) 발생 제 foo3 만나면 컴파일러는 int을 반환하는 함수임을 추측 main.c 편집. 컴파일러가 foo3의 정의를 볼 때 올바르게 불평합니다.

-Wstrict-prototypes 경고 option ~ gcc을 사용할 수 있습니다 (단, 항상 사용하는 것이 좋습니다 -Wall이 암시합니다).

링크 타임에 C 함수의 형식 (및 서명)은 중요하지 않습니다. 링커는 이름을 사용하여 작업을 수행합니다 (C++에서는 name mangling을 사용합니다). 물론 잘못된 인수 나 결과를 가진 함수를 호출하는 것은 undefined behavior입니다.

좋은 기존 방법은 소스 파일 (이 복사하고이 선언을 붙여 가지고 방지에 헤더 파일 사용 된 모든 공공 기능 및 유형 (상수)와 include를 선언 공통 헤더 파일을 가지고있다 여러번). 그래서 당신은

// file myheader.h 
#ifndef MY_HEADER_INCLUDED 
#define MY_HEADER_INCLUDED 
void foo1(void); 
void foo2(void); 
void foo3(void); 
#endif /*MY_HEADER_INCLUDED*/ 

같은 새로운 헤더 파일 myheader.h이 whould 당신은 (거기 #include <stdio.h> 지시 후) 모든 소스 파일에 #include "myheader.h"을 추가합니다. MY_HEADER_INCLUDED으로 include guard 트릭을 확인하십시오.

실제로, 헤더 파일에는 일반적으로 프로그램의 API을 설명하는 주석이 들어 있습니다.

GNU make에 대해 자세히 알아보십시오. 다중 소스 코드 파일 프로그램을 쉽게 만들 수 있습니다 (make을 실행하여 컴파일하고 빌드하면됩니다). Makefilethisthat 예를 참조하십시오. C preprocessing은 C 컴파일의 첫 단계라고 이해하십시오.

+0

귀중한 정보를 위해 thankyou. 한 가지 더 의심 스럽다. main.c에서 이전에 선언하지 않은 foo3()과 같이 main()에서 처음으로 나타나는 경우 foo2() 및 foo1()에 대해 충돌하는 유형 경고가 표시되지 않는 이유는 무엇입니까? – Akhil

+0

링크 시간 최적화가 필요합니다. 그러나 중요한 것은 헤더 파일을 작성하고 사용하는 습관을 갖고 거기에 모든 공개 된 것을 선언하는 것입니다. –

+0

오케이. main.c 컴파일은 foo3.c의 경고를 보여줄 뿐이며 main.c 내에서만 정의 된 함수이기 때문입니다. 따라서 위의 foo3()에 대한 경고는 main.c에서 유일한 경고이며 다른 함수는 main.c의 컴파일 중에 int 유형을 반환한다고 가정하므로 main()의 컴파일 중에 정의가 발생하지 않으므로 경고가 발생하지 않습니다. .기음. 귀중한 지원에 감사드립니다. – Akhil