C++ Chapter 1.4 : 컴파일, 헤더 파일 만들기, 헤더 가드가 필요한 이유

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!


컴파일 과정

  • 컴파일의 역할
    • 문법 체크 + static 한 영역들 메모리 할당 일을 수행한다.
      • 프로그램이 실행되기 전에 미리 메모리에 할당되어 있어야 하는 부분들. 런타임 때 메모리가 결정되는 부분들 말고!
  • 헤더 파일은 컴파일 되지 않는다.
    • 헤더 파일은 include 한 cpp 파일 내에 전체 복사될 뿐이다.
  • cpp 파일들은 각각 독립적으로 컴파일 된다.
  • 그 다음에 컴파일이 완료된 cpp 파일들을 링킹 한다.


헤더 파일 만들기

  • 한 코드 파일에 모든 내용을 다 넣는건 좋지 않다.
    • #include "add.h" 해주면
      • add.h 헤더파일에 정의해 놓은 함수와 변수들을 마음대로 사용 가능하다.
      • add.h 헤더파일은 프로젝트와 동일한 위치에 있어야 한다.
        • 다른 위치라면 #include “myfolder/add.h” 이런식으로 상대 파일 경로를 써주어야 함
      • 단, add.cpp이 있다면 add.cpp도 같은 위치여야함.


헤더 가드

  • 헤더 파일 에는 함수의 프로토 타입만 쓰고
  • 헤더와 이름이 같은 cpp파일 에는 함수의 정의와 바디를 쓰고
  • include한 cpp파일 에서 이 함수들을 사용한다.

ex)

  • add.h 라는 헤더 파일에 int add( int x, int y) 라는 함수의 프로토타입이 있는 상태
  • add.cpp 라는 코드 파일에 int add(int x, int y) 라는 함수의 바디가 있는 상태
  • 만약 이런 상황에서 add.cpp 코드 파일을 remove 시켰다면?
    • 컴파일은 성공한다.
      • add.h 헤더 파일의 int add(int x, int y); 프로토타입만 가져와 검사하기 때문
    • 단 add.cpp 파일은 무시되서 함수의 바디가 무시되기 떄문에 링킹 에러가 난다. 링킹은 실패함.
      • 문법상으론 OK지만 실행할 땐 문제가 생기는 것

cf)

  • remove : 파일 삭제는 아니고 그냥 이 파일을 무시하라는 의미. 빌드할 때 사용하지 않겠다는 의미.
  • delete : 파일 영구 삭제

헤더 가드를 사용하는 이유 : 헤더 재 정의를 방지 하기 위하여!

  • 보통 헤더파일엔 프로토타입만 적고 이름이 같은 cpp파일엔 바디를 적는 경우가 깔끔하지만
  • 그냥 헤더 파일 안에서 함수 바디까지 다 정의하는 경우도 있다.
    • 이런 경우 생기는 문제
      • 똑같은 헤더 파일이 이중으로 불러와져 똑같은 바디가 두번 복사되는 일

        ex)

        add.h

        • int add 함수의 바디까지 add.h 헤더파일 안에 다 정의했다면
          int add (int x, int y ) 
          {
          	return x + y;
          }
        

        work.h

        • work.h의 work 함수 내부에서 add.h의 add(1,2) 호출하는 상태라면
          #include "add.h"
        
          void work()
          {
          	add(1, 2); 
          }
        

        main.cpp

        • main.cpp 컴파일시
          • cout << add(3, 4) << endl;
            • add.h로부터 add함수정의&바디를 main.cpp에 복사해옴
          • work();
            • work.h → add함수, work함수정의&바디를 main.cpp에 복사해옴
            • add (1, 2) 호출 → add.h → add함수정의&바디를 main.cpp에 복사해옴
            #include "add.h"
            #include "work.h"
          
            int main()
            {
            	cout << add(3, 4) << endl;
            	work();
            }
          
          • add함수 정의&바디가 main.cpp에 중복 복사된다.
            • 똑같은 함수가 두번이나 정의되는 것이니 에러.
            • 컴파일시 내부적으로 아래와 같은 상황이 되버린다.
              int add (int x, int y ) // 바디가 두번 복사됨
              {
              	return x + y;
              }
              int add (int x, int y ) // 바디가 두번 복사됨
              {
              	return x + y;
              }
              void work()
              {
              	add(1, 2); 
              }
              int main()
              {
              	cout << add(3, 4) << endl;
              	work();
              }
            
        • 헤더 가드를 쓰면 이렇게 함수 바디 정의가 두번 중복되는 문제를 방지해준다.

헤더 가드 종류

1. #ifndef, #endif

  • #ifndef
    • MY_ADD가 이미 정의 되어 있지 않다면 ( if not define )
    • 즉 아직 include 되지 않은 부분이라면
  • #endif
    • #ifndef 부터 endif까지 이 범위의 복사를 허용해라.
  • 예시
    • MY_ADD가 define 를 통해 정의되어 있으니

        #ifndef MY_ADD
        #define MY_ADD
      
        int add(int a, int b)
        {
        	return a + b;
        }
        #endif
      
    • 이미 이전에 include가 된 파일이라면 MY_ADD가 정의되어 있을테니

      • 아래 범위를 처리하지 않는다.
        • 이처럼 헤더 파일 재 정의를 막음 (→ 함수 정의 2번 복사를 막음)
          int add(int a, int b)
          {
          	return a + b;
          }
        

2. #pragma once

  • 간단하게 한 줄이면 해당 헤더 파일 전체의 재정의를 막는다.

      #pragma once
    
      int add(int a, int b)
      {
      	return a + b;
      }
    
  • C++공식 언어는 아니기 때문에 모든 컴파일러가 지원하는 것은 아니다.

    • pragma once를 지원하지 않는 컴파일러라면 ifndef, endif 같은 공식 헤더가드를 사용하기


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

댓글남기기