빌드 중에 나오는 warning 대부분은 아무런 문제가 없는 경우가 많은데 이 때문에 정작 수정이 필요한 warning은 묻혀 버리는 경우가 있다. 때문에 뛰어난 개발자는 warning을 완전히 없애고, 개발 중에도 발생하는 warning은 즉시 처리하여 전체 빌드중 warning은 0개가 나오도록 소스코드를 다듬는다.
가능한 많은 워닝이 노출되도록 설정하고, 발생한 모든 워닝을 제거한다. 프로젝트 속성에서 Warning Level 4 설정하여 최대한 많은 워닝이 노출되도록한다.
워닝중에는 주위가 필요한 워닝이 있다. 예를 들어 다음과 같은 코드를 보자
inline void ClearSection(LPCTSTR szSection)
{
::WritePrivateProfileString(m_sSection, NULL, NULL, m_sFile);
}
위 코드는 warning C4100: 'szSection' : unreferenced formal parameter 와 같은 에러를 리턴한다. szSection이 정의가 되어 있지만 사용되지 않고 있다고 알려준다. m_sSetion이 아니라 szSection을 입력하거나 파라미터를 없애 void형으로 수정하는 것이 올바른 코드이다. 이 워닝을 에러로 처리해서 워닝을 수정하지 않고는 빌드가 되지 않도록 만드는 방법을 애용하고 있다. 이것은 워닝 레벨4에서만 노출되기에 워닝 레벨이 기본값 3이었다면 나중에 발견하기 어려운 버그로 남을 뻔 했다.
#pragma warning(error:4100)
#pragma warning(error:4715) //warning C4715: 'a' : not all control paths return a value
#pragma warning(error:4700) //warning C4700: uninitialized local variable 'a' used
#pragma warning(error:4706) //warning C4706: assignment within conditional expression
#pragma warning(error:4101) //warning C4101: 'b' : unreferenced local variable
#pragma warning(error:4717) //warning C4717: recursive on all control paths, function will cause runtime stack overflow
#pragma warning(error:4189) //warning C4189: 'a' : local variable is initialized but not referenced
#pragma warning(error:4018) //warning C4018: '<=', '<' ,'>=', '>' signed/unsigned mismatch
#pragma warning(error:4389) //warning C4389: '==' : signed/unsigned mismatch
#pragma warning(error:4800) //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(error:4100) //warning C4100: 'szSection' : unreferenced formal parameter
이런 경우 불 필요하게 처리하고 싶지 않은 워닝이 뜨수도 있는데 그런 경우는 해당 워닝을 끄면 된다.
#pragma warning(disable:4482) //warning C4482: nonstandard extension used: enum 'CListCtrlSortClass::SortDataType' used in qualified name
#pragma warning(disable:4138) //warning C4138: '*/' found outside of comment
빌드 과정에 메시지 노출시키기
#ifndef chSTR
# define chSTR(x) #x
# define chSTR2(x) chSTR(x)
#endif
#define toteam(desc) message(__FILE__ "(" chSTR2(__LINE__) ") : toTEAM> " desc)
아래 코드는 EasyRegistry 프로젝트에서 다국어 언어 xml 파일을 로드하는 코드인데 디버그 모드에서는 xml 파일은 상위폴더의 release폴더에서 로드를 한다. Debug폴더와 Release폴더로 빌드 결과물은 다른 폴더에 생성이 되지만 xml 파일과 같은 리소스는 중복시키지 않고 하나의 폴더에서 관리하기 때문이다. (xml 수정이 두 군데의 파일을 수정해야 하는 번거로움을 제거)
TCHAR path[MAX_PATH] = { NULL };
GetModuleFileName(NULL, path, _countof(path));
PathRemoveFileSpec(path);
#ifdef _DEBUG
#pragma toteam("디버그모드에서는 상위 relese폴더의 res에서 locale xml을 로드합니다.. ")
// 디버그모드에서 Release모드의 res폴더에서 xml을 로드한다...
PathAppend(path, _T("..\\release"));
#endif
PathAppend(path, _T("res"));
PathAppend(path, _T("ko-KR.xml"));
NVerify(LoadStringBundle(path)) << L"xmlpath=" <<path;
이 코드가 빌드가 되면
2>d:\newproject\sdp_for_win32\src\easyregistry\easyregistry.cpp(78) : toTEAM> 디버그모드에서는 상위 relese폴더의 res에서 locale xml을 로드합니다..
빌드로그에 메시지가 노출이 되는데, 중요한 점은 이 라인을 더블클릭하면 해당 소스의 라인으로 이동된다는 점이다.