MFC 다이얼로그 기반 프로젝트를 생성하고 모던 C++의 std::min이나 std::max를 사용하려고 할 때, 다음과 같은 오류로 컴파일이 안될 때...
발생 오류 코드:
E0040: 식별자가 필요합니다.
C2589: '(': 토큰이 불분명합니다.
C2059: 구문 오류: '('
사용코드
#define NOMINMAX
#include <windows.h>
#include <algorithm>
int val = std::min(a, b); // 오류 발생!
원인
이유는 MFC 프로젝트의 미리 컴파일된 헤더(Precompiled Header, PCH) 처리 순서 때문이다.
MFC 프로젝트는 컴파일 속도를 높이기 위해 pch.h (구버전 stdafx.h)를 가장 먼저 컴파일한다.
개발자가 작성한 .cpp 파일의 첫 줄에 #define NOMINMAX를 적었더라도, 컴파일러는 이미 pch.h 내부에서 windows.h를 로드해버린 상태이다.
즉, NOMINMAX가 정의되기도 전에 이미 Windows의 min/max 매크로가 전역에 퍼져버려 std::min과 충돌하는 것이다.
해결방법
1. 프로젝트 속성에서 전역 설정하기
소스 파일마다 #define을 적을 필요 없이 가장 깔끔하게 해결가능
[프로젝트] -> [속성(Properties)] (단축키: Alt + F7)
[구성 속성] -> [C/C++] -> [전처리기] 선택
[전처리기 정의] 항목 편집
목록에 NOMINMAX 추가 후 확인
이렇게 하면 프로젝트 내의 모든 파일에서 Windows의 min/max 매크로가 비활성화된다.
2. 미리 컴파일된 헤더(pch.h) 수정하기
프로젝트 설정 변경이 싫다면 pch.h (또는 framework.h) 파일의 최상단에 정의해야 한다..
pch.h (또는 framework.h)
#ifndef PCH_H
#define PCH_H
#define NOMINMAX // 반드시 include 이전에 선언!
#include "framework.h"
// ...
#endif
3. 코드 레벨에서 괄호() 사용하기
설정을 건드리기 귀찮거나, 레거시 코드 때문에 매크로를 꺼서는 안 되는 상황이라면 함수 호출 부에 괄호를 감싸서 해결할 수 있다.
cpp
// 매크로 확장을 막기 위해 함수명을 괄호로 감쌈
int result = (std::min)(a, b);
결론
MFC 환경에서 std::algorithm을 사용할 때는 프로젝트 속성의 전처리기 정의에 NOMINMAX를 추가
소스 코드 상단의 #define은 PCH에 밀려 무시될 수 있다.
'프로그래밍 > MFC' 카테고리의 다른 글
| [MFC]리소스 데이터를 파일로 저장 (0) | 2020.06.02 |
|---|---|
| 64bit 컴파일시 ON_WM_TIMER() 에러 해결방법 (0) | 2015.06.12 |
| library linking error msvcprt.lib(MSVCP90.dll) : error LNK2005: "public: __thiscall std: (0) | 2013.08.28 |
| warning MSB8012: TargetExt(.dll)이(가) Linker의 OutputFile 속성 값(....)과 일치하지 않습니다 (0) | 2013.08.22 |
| MFC 현재 실행파일 경로얻기 (0) | 2013.07.05 |




















































