C++ Chapter 1.4 : 컴파일, 헤더 파일 만들기, 헤더 가드가 필요한 이유
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
컴파일 과정
- 컴파일의 역할
- 문법 체크 + static 한 영역들 메모리 할당 일을 수행한다.
- 프로그램이 실행되기 전에 미리 메모리에 할당되어 있어야 하는 부분들. 런타임 때 메모리가 결정되는 부분들 말고!
- 문법 체크 + 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.h 헤더 파일의
- 단 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(); }
- cout << add(3, 4) << endl;
- 헤더 가드를 쓰면 이렇게 함수 바디 정의가 두번 중복되는 문제를 방지해준다.
-
- 이런 경우 생기는 문제
헤더 가드 종류
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 같은 공식 헤더가드를 사용하기
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기