C/C++ 언어에서 헤더의 중복 선언을 방지하기 위해 #pragma once[각주:1]를 사용한다.
그런데, #pragma once를 써도 링크 오류가 발생하는 경우가 있다.
아래와 같은 간단한 프로그램들을 보자.
1 2 3 4 5 6 7 8 9 10 | // CTest1.h: 헤더 파일 // #pragma once class CTest1{ public : int Func(); }; |
1 2 3 4 5 6 7 8 | // CTest1.cpp: 클래스 동작을 정의함 // #include "CTest1.h" int CTest1::Func() { return 1; } |
1 2 3 4 5 6 7 8 9 10 | #include <iostream> #include "CTest1.h" int main() { CTest1 test1; std::cout << test1.Func() << std::endl; } |
물론 이 코드는 정상적으로 동작한다.
그런데, 어떤 이유로 다음과 같이 변형하게 될 일이 생겼다고 하자.
1 2 3 4 5 6 7 8 9 10 11 | // CTest1.h: 헤더 파일 // #pragma once class CTest1{ public : int Func(); }; CTest1 test1; |
1 2 3 4 5 6 7 8 | #include <iostream> #include "CTest1.h" int main() { std::cout << test1.Func() << std::endl; } |
이 코드에서만 보면 저렇게 쓸 일은 없겠지만, 실제로 비슷한 경우는 종종 발생한다.
저 클래스의 인스턴스를 하나만 생성해서 공유해야 되는 경우라든지...
하지만, 저 코드를 컴파일해보면 다음과 같은 오류가 발생한다.
코드를 #pragma once로 막아두었지만, 여러 번 정의되었다는 LNK2005 오류가 발생하는 것이다.
편하게(?) 생각하면 test1이라는 인스턴스를 공유하려고 하는 것 같지만 컴파일러는 그렇게 생각하지 않는다.
메인 함수가 있는 cpp 파일과 CTest1.cpp 에서 모두 CTest1.h 를 include하고, 컴파일 시점까지는 아무런 문제가 없다가 링킹 시점에서 test1 이라는 인스턴스가 중복되어 오류가 발생하는 것.
만약 의도가 test1이라는 인스턴스를 다른 클래스 등과 공유하는 것이라면 extern을 활용해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 | // CTest1.h: 헤더 파일 // #pragma once class CTest1{ public : int Func();}; extern CTest1 test1; |
1 2 3 4 5 6 7 8 9 10 | // CTest1.cpp: 클래스 동작을 정의함 // #include "CTest1.h" int CTest1::Func() { return 1; } CTest1 test1; |
시놀로지 NAS에서 웹메일 서버 돌리기 (2) | 2022.02.02 |
---|---|
의외로들 잘못 이해하는 그래픽 카드 보조전원 (2) | 2022.01.25 |
윈도우에서 OpenDDS 제대로 컴파일 하기: 추가 사항 (0) | 2021.12.22 |
Log4j 사태로 대체 정부는 왜 까는 거지? (2) | 2021.12.12 |
윈도우에서 OpenDDS 제대로 컴파일 하기 #4 (0) | 2021.12.07 |
내 블로그 - 관리자 홈 전환 |
Q
Q
|
---|---|
새 글 쓰기 |
W
W
|
글 수정 (권한 있는 경우) |
E
E
|
---|---|
댓글 영역으로 이동 |
C
C
|
이 페이지의 URL 복사 |
S
S
|
---|---|
맨 위로 이동 |
T
T
|
티스토리 홈 이동 |
H
H
|
단축키 안내 |
Shift + /
⇧ + /
|
* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.