파일의 분할과 다중 파일 컴파일
C언어를 사용하면서 파일의 분할을 했을 때 다른 파일에 정의한 변수나 함수를 불러오려면 어떻게 해야하는지 생각해 본적 있나?
무의식적으로 그냥 #include로 standard header file만을 불러다 쓴건 아닌가?
수업에서 배운 내용으로 이번에 한 번 정리 해보려고 한다.
위의 상황처럼 여러 파일로 분할하여 코드를 짰을 때 어떻게 불러다 쓸지 생각해봤는가?
이 경우에는 extern을 사용해서 다른 파일의 변수와 함수들을 컴파일하여 사용할 것이다.
extern의 사용법은 간단하다.
extern 반환타입 함수명(매개변수타입);
extern 자료형 변수명;
위와 같은 선언으로 다른 파일에서 정의한 변수와 함수를 사용할 수 있다.
그 다음은 무의식적으로 그냥 새로운 파일을 만들면 항상 쓰여있는 #include <stdin.h>과 같은 standard header file에 대해 알아보자.
- 위키 백과에 적혀있는 헤더 파일의 정의
컴퓨터 프로그래밍에서, 특히 C와 C++ 프로그래밍 언어에서, 헤더 파일(header file) 또는 인클루드 파일(include file)은 컴파일러에 의해 다른 소스 파일에 자동으로 포함된 소스 코드의 파일이다. 일반적으로 헤더 파일들은 다른 소스 파일 속의 첫 부분에 포함된다.
C와 C++ 프로그래밍 언어에서, 표준 라이브러리 함수는 전통적으로 헤더 파일 안에서 선언되어 있다. C 표준 라이브러리와 C++ 표준 라이브러리에 많은 함수들이 존재한다. 함수들은 사용자가 API 수준에서 알아야 한다. 따라서 개발 도구를 만드는 입장에서, 함수 자체를 설계하고 코딩을 한 측에서 제공해야 한다. 라이브러리 오브젝트 코드는 파일로 존재하고 헤더 파일에 함수나 변수의 형이 선언되어 있으므로 사용자 측에서 붙여 사용하면 된다. 사용자 측에서 사용한 라이브러리는 라이브러리 파일의 코드를 링커가 응용 프로그램에 붙여 전체 실행 코드가 완성된다. 결국 헤더 파일의 형을 사용하여 라이브러리 사용자의 인클루드에 의해 함수 호출이 방식이 결정된다.
헤더파일은 정리하자면 외부에 있는 파일을 불러다가 사용하는 자바의 import와 비슷하다.
표준 헤더파일과 프로그래머가 정의하는 헤더파일의 디자인은 아래와 같다.
표준 헤더파일
#include <헤더파일 이름>
프로그래머가 정의한 헤더파일
#include "헤더파일 이름"
이제는 헤더파일의 중복삽입 문제에 대해서 알아보자.
헤더파일을 직접적으로 또는 간접적으로 두 번 이상 포함하는 것 자체는 문제가 안된다. 그러나 두 번 이상 포함시킨 헤더파일의 내용에 따라서 문제가 될 수 있다.
일반적으로 선언은 두 번이상 포함시켜도 문제되지 않는다. 그러나 정의는 두 번 이상 포함시키면 문제가 된다.
그래서 구조체를 정의한 파일(A)을 다른 파일에서 include하고 그 다음에 그 파일(B)과 A를 다른 파일 C에서 둘다 include하는 경우, 하나의 구조체가 두번 include되어 두번 정의되는 상황이 될 수 있다. 이 경우 구조체는 하나의 파일에서 중복될 수 없기 때문에 문제가 된다.
그래서 이런 문제를 해결하기 위해서는 #ifndef #define 패턴을 이용하면 순환 참조나 중복 인클루드를 막을 수 있다.
#ifndef(if not define) 특정 키워드의 정의 여부를 확인하여 정의되지 않았을 경우만 include할 수 있게 만든다.
그럼 정의 되지 않은 키워드일 경우 #ifndef부터 #endif까지 정의된다. 그렇지 않고 정의된 키워드라면 #endif까지의 코드는 무시된다.
이런 매커니즘을 인클루드 가드(Include guards)라고 한다.