- WIN32_LEAN_AND_MEANとは何なのか
- WIN32_LEAN_AND_MEANを使うと何が起こるのか
Visual Studio 2019でC++のDLLプロジェクトを作ると、最初から存在するヘッダーファイルに”framework.h”というものがあります。このファイルは、プリコンパイル済みヘッダーファイルと呼ばれるものです。(Visual Studio 2017以前は、stdafx.h) 以下原文にあるように、ファイルの目的は、ビルドスピードを速めることにあります。
When you create a new project in Visual Studio, a precompiled header file named pch.h is added to the project. (In Visual Studio 2017 and earlier, the file was called stdafx.h.) The purpose of the file is to speed up the build process.
Microsoft Docsより引用
ビルドスピードの高速化に一役買っているのが、framework.hの中でdefine定義されている「WIN32_LEAN_AND_MEAN」です。この定義が何なのか、そして、その効果について解説します。
実行環境は下表の通りです。
開発環境 | Microsoft Visual Studio Community 2019 Version 16.11.7 |
OS | Windows 10 バージョン21H1 |
WIN32_LEAN_AND_MEAN
概要
WIN32_LEAN_AND_MEANは、windows.hの内部で、条件付きコンパイル定義に使われています。具体的には、”ifndef WIN32_LEAN_AND_MEAN”と書かれており、”WIN32_LEAN_AND_MEAN”が define定義されていれば、プリプロセッサで囲まれた、”ヘッダーファイルのインクルードをスキップする”、という働きをします。
逆に言えば、”WIN32_LEAN_AND_MEAN”のdefine定義がない場合は、インクルードを行うことになるので、ビルドスピードは遅くなります。
何がスキップされる?
スキップされるヘッダーファイルは
- #include <cderr.h>
- #include <dde.h>
- #include <ddeml.h>
をはじめとする18ファイルが対象です。具体的には、windows.hを開いて確認してください。
これらのファイルがどういう内容なのかについては、内容が難解であり、また、過去の遺物でもあるようなので、詳しく触れません。平たく言うと、16bitから32bitへ移行した際に、不要となったヘッダーファイルを、”WIN32_LEAN_AND_MEAN”を定義することでスキップできるようになります。
本定義は、Windows 95の時代に追加されたようです。
検証
前準備
前準備として、ビルドの時間計測を有効にします。これにより、”WIN32_LEAN_AND_MEAN”の有無によるビルドスピードの差を確認します。
「プロジェクトおよびソリューション」→「VC++ プロジェクトの設定」から”ビルド時間”の設定を”いいえ”から”はい”に変更しておきます。
検証用プログラム
検証用に、C++ コンソールアプリケーションのプロジェクトを作成します。コードは何でもよいです。1行目のdefine定義をコメントアウトした場合と、コメント解除した場合の2通りでビルドを行います。
//#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <Windows.h>
void test(int num)
{
printf("test=%d\n", num);
return ;
}
int main(void)
{
int a = 0;
printf("Hello,world a=%d\n",a);
test(100);
return 0;
}
測定結果
測定結果です。”WIN32_LEAN_AND_MEAN”を定義すると、確かにビルドが高速化されました。
ビルド時間(ミリ秒) | |
WIN32_LEAN_AND_MEAN有り | 549 |
WIN32_LEAN_AND_MEAN無し | 1,017 |
この検証では、ビルド対象プロジェクトが小さなものだったため、偏差が小さかったかもしれません。実際の製品プログラムでビルドスピードが遅いというケースでは、役に立つかもしれません。
まとめ
“WIN32_LEAN_AND_MEAN”というdefine定義は、冒頭でも述べたように、DLLプロジェクトであれば、初期状態からプリコンパイル済みヘッダーファイルの中に、define定義が書かれています。そのままヘッダーファイルを使う場合には、意識する必要はありません。プリコンパイル済みヘッダーファイルは能動的にプリコンパイル済みヘッダーを使用しない、と設定することもできます。その場合で、windows.hをインクルードする場合は、自分で今回のdefine定義を記載する必要があるので、注意してください。
参考リンク
■Windowsヘッダーファイル
■プリコンパイル済みヘッダーファイル
コメント