#include 순서의 중요성

Serepha0921·2025년 5월 16일

SDK 파일을 받아 C++로 DLL wrapper를 만들던 중, 이전에는 전혀 없던 컴파일 오류들이 발생했다. 같은 SDK를 사용할 때 .exe 파일을 만들던 프로젝트에서는 오류가 전혀 없었고, DLL 프로젝트 빌드할 때만 오류가 발생했다.

문제상황


초기 코드에서의 #include 순서는 다음과 같았다:

cppCopyEdit#include "SDK1.h"
#include "SDK2.h"
#include <opencv2/opencv.hpp>

이 코드는 EXE 프로젝트에서는 정상적으로 컴파일되었지만,
DLL 프로젝트에서 컴파일하자 다음과 같은 구문오류들이 SDK 헤더에서 발생했다:

bashCopyEdit'(': illegal token on right side of '::'
'std::tr1': warning STL4002: The non-Standard std::tr1 namespace and TR1-only machinery are deprecated and will be REMOVED.
syntax error: ')' was unexpected here; expected ';'
syntax error: unexpected token ')' following 'expression-statement'

해결방법


#include 순서를 바꾸었을 뿐인데, 문제가 완전히 해결되었다.

#include <opencv2/opencv.hpp>
#include "SDK1.h"
#include "SDK2.h"

이렇게 순서를 바꾸자 SDK 헤더파일에서 발생하던 구문오류가 전부 사라졌다.

원인 분석


컴파일러는 헤더를 포함한 순서에 따라 전처리기 매크로 정의, 타입 선언, 템플릿 해석 방식 등이 달라질 수 있다.
OpenCV 같은 대형 라이브러리를 먼저 include하면 내부적으로

  • #define NOMINMAX
    이건 SDK의 헤더파일에서 c++버전차이 인거 같아서 오류를 무시했다.
  • <memory> 같은 표준 헤더 선행 포함등이 이루어져 이후에 포함되는 SDK 헤더와 매크로 충돌, 네임스페이스 문제를 예방할 수 있다.
  • 모든 관련 매크로(예: 경고 억제기, 구성 플래그)를 정의한 후, 해당 매크로에 의존하는 헤더를 포함해야 합니다. 헤더 파일은 전처리기 정의에 의존하여 동작을 변경할 수 있으므로, 예기치 않은 컴파일 문제를 방지하기 위해 정의와 포함의 순서가 중요합니다. SDK는 opencv에 의존하고 있다.

EXE 빌드와 DLL 빌드는 프로젝트 속성이나 런타임 환경이 달라질 수 있기 때문에,
헤더 포함 순서에 따라 빌드 결과가 달라질 수 있다.


결론


C++에서는 #include 순서가 실제로 빌드 결과에 영향을 줄 수 있다.
특히 외부 SDK, 대형 라이브러리(OpenCV, Windows API 등), 매크로 사용이 많은 코드베이스에서는 더욱 주의해야 한다.

정리:

  • #include 순서를 무시하지 말자.
  • #define, #pragma, extern "C" 등의 전처리기는 포함 순서에 따라 결과가 달라진다.
  • DLL 환경과 EXE환경은 다르다
profile
안녕하세요. 뉴비 입니다

0개의 댓글