따배씨++ (11. 헤더, 헤더가드)

김동우·2021년 2월 24일
0

안녕하십니까. 김동우입니다.

이번 글에서는 헤더와 헤더가드에 대해 조금 얘기를 해볼까 합니다.

헤더는 전에 말씀드렸듯 내장함수를 가지고 있는 파일입니다.

이러한 파일의 분할을 모듈화의 기본이고, 유지보수에 상당히 편리한 이점을 가져다 줍니다.

그렇기에 우리는 함수를 작성할 상황이 오면

  • 헤더를 만들고 헤더 내에 전방선언을 실시한다.
  • 동명의 cpp 파일을 만들고 함수 내용을 작성한다.
  • main함수가 있는 cpp 파일에서 include를 통해 헤더를 불러오고, 해당 파일에서 헤더의 함수들을 호출한다.

의 순서대로 작성을 하면 되겠습니다.

자, 그럼 이러한 헤더파일을 예시로 작성해보고, 하나씩 까봅시다.

  • add.h
#pragma once 
// 헤더가드

int add(int x, int y);
  • add.cpp
int add(int x, int y)
{
	return x + y;
}
// definition, 정의, body
  • main.cpp
#include <iostream>
#include "add.h" 
// 빌드 폴더 내에 존재할 경우의 헤더 추가 
// 상대경로로 표시하는 경우도 있습니다.

using namespace std;

int main()
{
	cout << add(1, 2) << endl;

	return 0;

}

이러한 순서로 작성을 하시면 되는데, 이 때 헤더파일 내에 처음 보는 개념이 등장하게 됩니다.

아, 그리고 앞으로 분할된 코드를 올릴 때에는 이러한 방식으로 올리겠습니다.

  1. 링킹에러

    우리가 파일을 나누었을 경우 처음 볼 수 있는 에러의 종류 중 하나는 링킹에러입니다.

    source file 폴더 내에 add.cpp 파일이 없는 경우에 링킹에러가 발생하는데, 이러한 에러가 발생하는 주된 이유는 헤더와 cpp 파일을 분리하기 때문입니다.

    즉, 헤더에서 전방선언을 분명 실시했고, main.cpp 내에서 사용했는데, cpp 파일이 존재하지 않아 body를 읽어올 수 없기 때문에 발생하는 것입니다.

    그러나 충격적이게도 헤더에 전방선언만 들어있어야만 하는 것은 아닙니다. cpp 파일과 헤더 파일을 둘 다 만드는 것은 생각보다 번거롭기 때문입니다. 그러니 헤더에 다 적는다면 어떨까요?

    우린 링킹에러를 방지할 수 있으며, 상당히 편리하게 코딩할 수 있을겁니다.

    이 처음 보는 에러를 극복하게 해주는 것, 우리는 이제 헤더가드에 대해 알 차례입니다.

  2. 헤더가드

    자, add.h 파일을 다시 한 번 봅시다.

    #pragma once 코드가 무슨 의미일까요?

    이 안에는 생각보다 많은 것들이 포함되어 있습니다.

    먼저, #ifndef, #define 개념이 포함되어 있습니다.

    즉, #include를 통해 불러올 경우 정의가 중복된다면, 다시 정의하지 말라는 말이 됩니다.

    너무 어렵죠?

    사전에 python, JS 등의 언어에서 사용하던 import-export 개념보다 low level에 위치한 개념입니다.

    타 언어에서 import한 뒤에 사용하지 않아도 우린 큰 문제가 없고, import한 변수나 함수가 여러 파일에서 겹치더라도 큰 문제가 없었습니다. 왜? 언어와 프레임워크들이 처리해주었으니까요.

    하지만 C++의 #include는 조금 다릅니다.

    include 된 파일의 함수를 여러 파일에서 중복으로 불러올 때, 파일 내에 헤더가드가 없거나 전처리기를 활용한 상단 선언이 없는 경우 정의된 함수가 중복된 상태로 해당 파일에 include 됩니다.

    또한 이는 빌드 과정에서 발생하는 에러 중 하나로 변하게 되고, 이는 상당히 비효율적인 코딩이 됩니다.

    우린 이를 막기 위해 헤더가드와 전처리기를 선언해주어야 하는데, 말씀드렸듯 헤더가드가 2개의 전처리기 내용을 포함하고 있으니 우린 헤더가드 하나만 선언해주면 되는 것입니다.

    이를 통해 우린 또 편리한 코딩을 할 수 있는 환경을 조성할 수 있는 것이죠.

    자, 정리해보면 헤더가드는

  • 헤더파일 내에 함수의 body를 정의할 수 있으니 링킹에러를 방지한다.

  • 그 이유에는 에러를 방지할 수 있는 전처리기 선언이 내포되어 있기 때문이다.

    로 알고 있으면 될 것 같습니다.

자, 그럼 이번 글은 여기서 마치겠습니다.

0개의 댓글

관련 채용 정보