소년코딩

01.12 - 헤더 가드 (header guard)

중복 정의 문제

식별자는 하나의 정의만 가질 수 있다. 따라서 변수 식별자를 두 번 이상 정의한 프로그램은 오류가 발생한다.

int main()
{
    int x; // 식별자 x에 대한 정의
    int x; // compile error: duplicate definition

    return 0;
}

함수를 두 번 이상 정의하는 프로그램도 컴파일 오류가 발생한다.

#include <iostream>

int foo()
{
    return 5;
}

int foo() // compile error: duplicate definition
{
    return 5;
}

int main()
{
    std::cout << foo();
    return 0;
}

이러한 프로그램은 헤더 파일을 이용해서 쉽게 수정할 수 있지만, 헤더 파일이 두 번 이상 포함될 경우 문제가 발생할 수 있다.

math.h:
int getSquareSides()
{
    return 4;
}
geometry.h:
#include "math.h"
main.cpp:
#include "math.h"
#include "geometry.h"

int main()
{
    return 0;
}

위 프로그램은 컴파일되지 않는다. main.cpp에서는 getSquareSides() 함수에 대한 정의가 있는 math.h를 복사한다. 또한 main.cpp는 math.h를 포함한 geometry.h를 복사한다.

모든 #include 지시자를 해결한 main.cpp는 다음과 같다.

int getSquareSides()  // from math.h
{
    return 4;
}

int getSquareSides() // from geometry.h
{
    return 4;
}

int main()
{
    return 0;
}

결국에 main.cpp는 중복된 함수 정의로 인해 컴파일 오류가 발생한다.


헤더 가드(Header guard)

헤더 가드(header guard)라는 메커니즘을 통해 위 문제를 해결할 수 있다. 헤더 가드는 조건부 컴파일 지시자를 사용한다.

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE

// 선언과 정의

#endif

위 헤더 파일이 포함(include)되면 SOME_UNIQUE_NAME_HERE가 정의되었는지 확인한다. 헤더 파일을 처음 include하면 SOME_UNIQUE_NAME_HERE는 정의되어 있지 않다. 그러므로 SOME_UNIQUE_NAME_HERE를 정의하고 헤더 파일의 내용을 include한다. 그러나 이전에 헤더 파일을 include 했다면 SOME_UNIQUE_NAME_HERE는 이미 정의되어 있기 때문에 헤더 파일 내용이 무시된다.

모든 헤더 파일에는 헤더 가드가 있어야 한다. SOME_UNIQUE_NAME_HERE은 일반적으로 _H가 붙은 헤더 파일의 이름을 사용한다.

math.h:
#ifndef MATH_H
#define MATH_H

int getSquareSides()
{
    return 4;
}

#endif

#pragma once

현재 많은 최신 컴파일러는 #pragma 지시자를 이용한 단순한 헤더 가드를 지원한다.

#pragma once

// your code here

#pragma once는 헤더 가드와 같은 기능을 하며, 짧다는 게 장점이다.

그러나 C++ 언어의 공식적인 부분이 아니므로 모든 컴파일러가 지원하는 것은 아니다. 호환성을 위해 헤더 가드를 사용하는 것이 좋다.


cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/1-10a-header-guards/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기