본문 바로가기

C Programming

헤더파일 중복 include 피하기(#ifndef vs #pragma once)

출처 : http://meetkei.com/wordpress/?p=30

헤더파일에는 일반적으로 클래스선언, 매크로 상수, 구조체 선언 등의 내용이 포함되어 있고 소스 작성시에 이 헤더파일을 필요로 하는 여러개의 파일에 #include 지시자를 통해 포함되게 된다. 단 하나의 파일에서만 포함된다면 큰 문제는 없지만, 여러개의 파일에 포함될 경우 중복정의 문제가 발생하게 된다. 예를 들어 클래스는 단 하나의 선언만을 가져야 하는데, 헤더파일이 여러 파일에 포함될 경우 포함된 횟수만큼 중복정의 되는 문제가 발생하여 컴파일을 할 수 없게 된다. 이 문제를 해결하기 위해서 많이 사용하는 방법이 #ifndef와 #define 지시자를 사용하여 중복을 체크하는 것이다.

userClass.h

#ifndef _USERCLASS_H_

#define _USERCLASS_H_

….(userClass 선언)….

#endif

위와 같은 형식으로 헤더 파일을 작성하면 중복정의 문제를 해결할 수 있다. 컴파일 시에 전처리기에 의해 _USERCLASS_H_ 매크로 상수의 정의 여부가 평가된다. _USERCLASS_H_이 정의 되어 있지 않는 경우 _USERCLASS_H_를 정의하고 나머지 코드를 실행한다. 다른 파일에 포함되어 이 파일의 내용이 다시한번 처리 될 때, #ifndef _USERCLASS_H_부분에서 _USERCLASS_H_상수가 정의되어 있으므로 #endif 사이에 위치하는 내용은 무시된다. 결과적으로 userClass.h파일가 포함되는 횟수에 상관없이 userClass는 단 하나의 선언만을 유지할 수 있다.


#pragma once 지시자도 동일한 기능을 한다.

차이가 있다면 위의 설명한 #ifndef..#define 방식의 경우에는 파일 내의 #ifndef _USERCLASS_H_ 부분을 평가해서 처리를 해야 하므로 파일이 포함될때마다 파일을 읽어야 하지만 #pragma once는 포함횟수의 관계없이 단 한번 처리를 하고 그 이후에는 파일을 읽지 않고도 컴파일러에 의해 처리가 되므로 결과적으로 빌드 시간을 절약할 수 있는 장점이 있다. 일부 구형 컴파일러에서는 지원이 안되는 경우도 있다.

구형 컴파일러에서도 동작하고 좀 더 범용적인 소스를 작성해야 하는 경우라면 #ifndef..#define 방식을 사용하고, 그 외의 경우에는 #pragma once를 사용하는 것을 추천한다.