Cpp プリコンパイル済ヘッダーファイル

提供:yonewiki

C++に戻る


本来の表記は「C++(Cpp) プリコンパイル済ヘッダーファイル」です。この記事に付けられた題名はテンプレート:記事名の制約から不正確なものとなっています。

※このページではC++にのみ存在する機能として、記事タイトルがC++ プリコンパイル済ヘッダーファイルになっています。

プリコンパイル済ヘッダーファイル

 プログラムは複数のファイルに分けて書くことができます。特にクラスを多用するC++では、ヘッダファイル部(関数の定義だけ)とプログラム部(定義された関数の実際の処理内容)とのペアが沢山出来上がります。大きなプロジェクトほどファイル数は膨大になり、50ファイル~500ファイル、あるいは5000ファイルとかもあり得ます。このメディアWikiのようなDBに記事内容を登録して、各ページごとにテキストを処理してHTMLとしての表示をするというプログラムでも3500ファイルほどで構成されています。PHPという言語ですが…もっと複雑な処理を必要とするwindowsのようなGUIアプリケーションなら、販売向けプログラム製品では膨大なファイル数になることは容易に想像がつきます。ですが、毎回、全部のファイルをコンパイルしていたら、もの凄くコンパイル時間がかかって、1回のコンパイル・リンク処理で15分~1時間くらいかかって、デバッグとかで繰り返し、試しに動かして見るということが、コンパイルの待ち時間にいくらでも耐えれて、集中力があって、時間が無尽蔵にあって、開発スピードは求めていない人でないとやりきれないです。個人でもウィンドウズアプリケーションを作る場合にはWindows.hファイルのような巨大なヘッダファイルを読み込むので、数十秒くらい時間がかかっていることを体感できると思います。いくつものファイルから呼ばれるヘッダファイルは、呼び出しをしているファイルが更新される都度、呼び出されたものの、まったく変更されていないにも関わらず、コンパイルしなおそうとします。この無駄なコンパイルを少し減らそうというのが、プリコンパイル済ヘッダーファイルの役目です。但し、何度も変更するファイルがプリコンパイルの対象に含まれるとプリコンパイルファイルを作成する機会が多くなり効果が目減りします。なのでプリコンパイルの対象は、

  1. あらゆるファイルからよく呼び出される。
  2. あまり変更する必要がなくなった。
  3. 規模が大きい。

そのようなファイルだけを一度プリコンパイル済ファイルを作っておくということをします。そういった作業をするために1つのヘッダファイルに、プリコンパイルしたいヘッダファイル群を呼び出すように作成して、プリコンパイル済みヘッダーファイルのオブジェクト(.pch)を作成します。


 少し前のVisualStudio2017あたりまでは新規プロジェクト作成をするウィザードでプログラミングを始めようとするとstdafx.hファイルが生成され、その中によく使うヘッダファイルであるstdio.hやwindows.hを呼び出していました。VisualStudio2019になるとpch.h(おそらくPre Compile Headerという意味の)ファイルが出来るだけで、その中のファイルは自分で作るという感じになりました。

使い方

 VisualStdio2019では、ウィザード形式を使わないプロジェクトテンプレートが多く、自分でpch.hファイルにあたるものを作るところから始まります。メニューの{プロジェクト}>{新しい項目の追加}を選択して表示されるダイアログでファイルの種類にヘッダファイルを選択して、ファイル名欄にpch.hというような名前のヘッダファイルを作ります。もう一つ、ダミーとして、そのプログラムファイルを作ります。メニューの{プロジェクト}>{新しい項目の追加}を選択して表示されるダイアログでファイルの種類にC++ファイルを選択してファイル名欄にpch.cppとしてファイルを作ります。pch.hに先ほどのべたようなプリコンパイルファイルにするべきヘッダをインクルードするように作り込みます。コンソールプログラムなら#incude <cstdio>をpch.hに入れてます。


 次に


 プロジェクトの設定を変更するので、メニューの{プロジェクト}>{プロパティ}を選択して表示されるダイアログで、左側のツリーから{C/C++}>{プリコンパイル済ヘッダ}を選択して、項目:プリコンパイル済ヘッダ=使用(/Yu)、項目:プリコンパイル済ヘッダファイル=pch.h、項目:プリコンパイル済ヘッダ出力ファイル:$(IntDir)$(TargetName).pch、のように設定します。そして、プリコンパイルヘッダファイルを作成するべきpch.cppとpch.hの組み合わせに対して作成のための設定が必要なので、ダイアログを閉じないまま、ファイル一覧が閲覧できるソリューションエクスプローラからpch.cppを選択して、左側のツリーから{C/C++}>{プリコンパイル済ヘッダ}の、項目:プリコンパイル済ヘッダ=作成(/Yc)、と設定します。


 既に、コンパイルしたことのあるプロジェクトは、リビルドを実施した方が良いと思いますが、この状態であれば、プリコンパイル済ヘッダーファイルを活用することが出来ます。


 小さなプロジェクトであれば、この他の選択肢として、プリコンパイル済ヘッダーの機能を使わない設定と全部で作成(/Yc)する設定が使えるものだと思います。プリコンパイル済機能を使わない設定では、毎回、変更された全ファイルと変更されたファイルから呼び出している共通のヘッダファイル部とそのプログラムの分も含めてコンパイルすることになります。プロジェクト全体で全てのヘッダーファイルがプリコンパイル済ヘッダーファイルを作成すると毎回プリコンパイルファイルを作り直して生成するようになります。単純にひと手間増えるだけです。


 pch.hファイルはプリコンパイルファイルの対象でありますが、各ファイルのpch.hが呼び出される前の部分もプリコンパイルの対象になります。pch.cppに対して作成(/Yc)と設定したので、pch.cppが変更されたら、プリコンパイル済ヘッダーファイルが作成されます。pch.cppから#include "pch.h"のようなインクルード文は必要です。pchファイルが更新されたら、プリコンパイル済ヘッダーファイルを作成するということを決めるだけのファイルです。pch.hの内容やpch.hから呼び出しているプログラムに変更があるか、pch.cppに変更があれば、プリコンパイル済みのヘッダーファイルは再作成されます。他のcppファイルで作成(/Yc)を設定してもプリコンパイル済ファイルの作成の機能が働きますが、よく更新されるcppにそれを設定したら、無駄にプリコンパイル済ファイルが生成される回数も増えるので、何も更新するよていのない、プロジェクトに読み込んだpch.cppに作成(/Yc)のオプションを定義した感じです。pchという名前ではなく、今までのstdafx.hという名前でプリコンパイル対象のヘッダーファイルを纏めてもいいです。


 出力ファイル:$(IntDir)$(TargetName).pchと設定したのですが、これはプロジェクト名を同じ名前でプリコンパイル済ヘッダーファイルのオブジェクトを作成するということを意味しています。xxxx.pchという、これまでに述べた通常の使い方においては、わりかし大きめのファイルがビルドあるいはリビルドをしたときに出来上がるはずです。