Channi Studies

[C++] 헤더가드 (header guards) | #pragma once, #ifndef 본문

C++/객체지향 프로그래밍 (OOP)

[C++] 헤더가드 (header guards) | #pragma once, #ifndef

Chan Lee 2023. 12. 28. 16:06

OOP를 사용하다보면,

한 프로젝트 내에서 다수의 헤더 파일과 cpp파일을 만들게 됩니다.

 

이 때 우리는 cpp 파일 내부에서,

include "header_name.h" 의 형태로 우리는 헤더 파일을 사용하게 됩니다.

 

하지만 cpp 파일이 다수가 되면서, 

한가지 헤더를 다수의 cpp 파일에서 중복 포함하게 될 경우가 발생할 수 있습니다.

이를 우리는 중복 정의 문제 라고도 부릅니다.

 

이런 형태는 컴파일 오류를 유발합니다.

(현대 C++ 컴파일러들은 이를 방지하기 위한 내부 메커니즘이 존재합니다만,

당연히 애초에 이러한 오류들을 방지하는 것이 우선입니다.)

 

그렇게 하기 위해서, 두가지 전처리문을 사용하는 방법이 존재합니다.

 


1. #ifndef, #define, #endif

 

 #ifndef, #define, #endif 입니다.

헤더 가드(Header Guard) 라는 메커니즘으로 불립니다.

 

사용 방법은 다음과 같습니다.

#ifndef EXAMPLE_H
#define EXAMLE_H

// 헤더 파일의 내용

#endif	//EXAMPLE_H

 

여기서 EXAMPLE_H 는 헤더 파일을 구분하는 매크로입니다.

 

매크로의 이름은 자율적으로 지어도 되나, 한 묶음 내부에서는 통일해야 하고,

관례적으로 헤더 파일의 이름을 따라갑니다.

 

위의 예시에 적용해보자면,

예시 속의 헤더 파일명은 example.h 였을 겁니다.

 

 

다시 돌아가서, 

#ifndef 는 if not defined 를 뜻합니다.

'정의 되지 않았다면' 다음을 행하라는 뜻입니다.

 

그럼 #define은 정의하라는 뜻이겠죠?

헤더 파일의 모든 내용을 이 아래에 위치합니다.

 

그리고 마지막으로 #endif는 조건문을 닫는 역할입니다.

if not defined 조건 하에 define을 실행했고, 이 definition을 종료하라는 뜻입니다.

이 #endif는 헤더 파일 최 하단에 위치해야 합니다.

 


2. #pragma once

 

또 다른 전처리문은 #pragma once 입니다.

동일한 역할을 하나, 컴파일러에서 지원하지 않을 경우가 존재할 수도 있습니다.

 

#pragma once는 매우 간단합니다.

1번 방법의 모든 표현을 헤더 파일 최상단에 #pragma once로 퉁칩니다.

 

#pragma once

// 헤더 파일 내용

 

매우 간단하다는 장점이 있지만, 표준 C++에는 포함되지 않아 있는 표현입니다.

대부분의 컴파일러에서는 지원하지만, 지원하지 않는 컴파일러들도 존재할 수 있습니다.

 


모든 파일에는 헤더가드 혹은 #pragma once가 필요합니다.

 

pragma once가 편리성 면에서 유리하지만,

호환성 면에서 헤더 가드를 사용하는 것이 훨씬 안전합니다.