C++/게임 개발자를 위한 C++ 문법

다중 포함 방지

iiblueblue 2024. 12. 26. 16:46
⊙ 헤더파일에 작성하는 다중 포함 방지문을 이해한다.

 

헤더 파일에 대해서 다시 배우면서 오랜만에 해더 파일을 작성했는데 모든 예제에 앞부분에 같은 문구가 있는 것을 보고 이것이 무엇인지 또 잊어버리기 전에 다시 한번 정리하기로 하였다.

 

헤더 파일 이중 선언

다중포함 방지문은 헤더파일의 이중 선언을 방지하기 위해 필요하다. 말 그대로 헤더파일을 두 번 선언하게 되는 것인데 어떻게 바보도 아니고 헤더파일을 두번 포함 시킬 수 있냐고 할 수 있다. 하지만 이런 문제는 한 스크립트 위에 헤더 파일을 두 번 적는 것 보다는 여러 개의 다른 헤더 파일들에 적혀있는 헤더 파일들이 얽히면서 생긴다.

 

아래와 같이 메인 함수가 들어간 cpp 파일이 있다고 생각해보자.

#include "Circle.h"
#include "Head.h"

int main()
{
	// 생략
}

Circle.h라는 헤더와 Head.h 헤더를 선언한 것을 볼 수 있다. 별로 문제 없어 보인다. 같은 헤더를 두 번 적은 것도 아니고 말이다. 하지만 만약 헤더가 이렇게 생겼다면 문제가 된다.

// Circle.h 파일
class Circle
{
	//생략
}
// Head.h 파일
#include "Circle.h"

class Head
{
	// 생략
}

헤더가 이렇게 생겼다고 생각하고 다시 코드를 보면 좀 문제가 있음을 알 수 있다. 처음에 "Circle.h"를 선언한 것까지는 좋았다. 하지만 그 다음 #include "Head.h"에서 문제가 생기고 만다. Circle.h는 이미 선언되었는데 Head.h를 선언하려고 보니까 Head.h에서는 또 Circle.h를 선언하고 있다. 이렇게 이중 선언이 되는 것이다. 생각보다 눈에 잘 띄지 않는다.

 

이런 경우를 대비하여 두 번 선언되지 않도록 해주는 전처리문이 있다.

 


 

다중포함 방지 방법 #1 : ifndef

// Circle.h 파일
#ifndef CIRCLE_H_ // 이 헤더가 정의되어 있지 않다면
#define CIRCLE_H_ // 아래 쭉 실행

class Circle
{
	//생략
}

#endif
// 정의 되어 있으면 스킵

두 번 포함되는 Circle.h 헤더에 조건문을 붙여서 한 번만 실행되도록 하는 코드다. 만약 헤더를 선언하려 했는데 이 헤더가 이미 정의되어 있지 않다면 #endif를 만날 때까지 아래 코드를 쭉 실행한다. 하지만 만약 이미 이 헤더가 정의 되어 있다면 #ifndef~#endif까지의 코드를 실행하지 않고 스킵한다.

#include "Circle.h"
#include "Head.h"

int main()
{
	// 생략
}

 

이제 다시 이 예제로 돌아오면 첫 줄에서 이미 Circle.h가 선언되고 난 후 Head.h를 선언하는데 더이상 문제는 없다. Head.h에 있는 Circle.h가 이중 선언되기 직전 이미 Circle.h가 선언되어 있는 것을 확인하고 Head.h에 있는 Circle.h는 선언되지 않고 스킵된다.

 


 

다중포함 방지 방법 #2 : pragma once

// Circle.h 파일
#pragma once

class Circle
{
	//생략
}

또 다른 방법으로는 두 번 참조되는 헤더파일 최상단에 #pragma once를 붙이는 방법이 있다. 이 문장을 붙이면 자동으로 두 번째 읽기조차 하지 않는다. 때문에 컴파일 속도를 올릴 수 있다. 어디서 많이 보신 분 같아 보이면 맞다. 비주얼 스튜디오에서 헤더파일을 생성하면 자동으로 최상단에 생기는 줄이다.

 


 

배운 내용 정리

  • 헤더 파일 이중선언은 여러 헤더에서 다양한 헤더를 정의하고 있기 때문에 생길 가능성이 높으며 이를 방지해야 한다.
  • #ifndef 문을 사용하면 헤더가 선언되기 전 이미 선언되어 있는지 확인하고 선언되어 있다면 선언을 스킵한다.
  • #pragma once는 자동으로 두 번째 읽기조차 하지 않는다.