WTLの警告「warning C4996...use _CRT_SECURE_NO_WARNINGS」を解決する

WTLを最新のものに入れ替えたら、それまで正常にビルドできていたソースコードで以下のような警告がでるようになった。

2>d:\_____sourcecode\_wtl\include\atlapp.h(851) : warning C4996: '_vswprintf': This function or variable may be unsafe. Consider using vswprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
2>        c:\program files\microsoft visual studio 9.0\vc\include\wchar.h(773) : '_vswprintf' の宣言を確認してください。
「atlapp.h」内の警告が出た個所を見てみると以下のようになっていた。
	inline int vsprintf_x(LPTSTR lpstrBuff, size_t cchBuff, LPCTSTR lpstrFormat, va_list args)
	{
#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
		return _vstprintf_s(lpstrBuff, cchBuff, lpstrFormat, args);
#else
		cchBuff;   // Avoid unused argument warning
		return _vstprintf(lpstrBuff, lpstrFormat, args);
#endif
	}

#ifによる分岐で、_SECURE_ATLが定義されていて、かつ、_ATL_MIN_CRTと_WIN32_WCEが未定義だと「_vstprintf_s」が、そうでなければ警告の出る「_vstprintf」が使われるようだ。

ここで「_WIN32_WCE」はWindows CE用の定義。通常のPC向けソースコードでは未定義がデフォルトなので問題にはならないだろう。

「_ATL_MIN_CRT」はATLの動的リンク時にランタイムライブラリの利用を極力減らすための定義。昔のプロジェクトではデフォルトで定義されていることがあったり、ビルドした実行ファイルのサイズが小さくなるというメリットがあるため敢えて定義する人もいる。そのため_ATL_MIN_CRTを利用する(利用したい)プロジェクトでは警告を解決することができない(警告を非表示にすることはできる)。

「_SECURE_ATL」は正体がよく分からないのでVisual Studioのincludeフォルダ内を検索してみた。
  D:\_____sourcecode\_WTL\include\atlapp.h(694):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(706):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(727):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(754):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(790):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(802):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(823):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(835):#if _SECURE_ATL
  D:\_____sourcecode\_WTL\include\atlapp.h(847):#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
  D:\_____sourcecode\_WTL\include\atlapp.h(857):#if _SECURE_ATL && !defined(_ATL_MIN_CRT) && !defined(_WIN32_WCE)
どうやらWTL内でのみ使われている定義のようだ。今回の警告が出た箇所と同じような分岐処理で「_s」タイプの関数とそうでない関数の使い分けをしているのだろう。バージョン関連の定義のように数値による分岐はなく、定義が有効かどうかだけを見ている。

以上のことから今回の警告を解決するには、_ATL_MIN_CRTの利用を諦めて、
#define	_SECURE_ATL	1
という定義をWTL関連がincludeされる前、「stdafx.h」の先頭に置く。 これで「_vstprintf_s」というより安全(とされている)関数が利用され、警告が表示されなくなる。


カテゴリー「WTL」 のエントリー