GCC ヘッダファイルのプリコンパイル

Open Tech Press - GCCのプリコンパイル済みヘッダはどの程度有用か

$ gcc hoge.h

とコマンド実行すれば,hoge.h と同じディレクトリに hoge.h.gch というバイナリが作成される.その後,hoge.h をインクルードしたソースファイルをコンパイルすると,hoge.h の代わりに hoge.h.gch が使用されてコンパイル時間が短縮される.なお,.h.gch 使用時と未使用時のコンパイル済みオブジェクトは完全一致した.

対象のヘッダファイルが他のヘッダファイルに依存しており,かつ依存しているヘッダファイルをインクルードしていない場合,構文解析に失敗して error や warning が大量に出力されるが,.h.gch ファイルは問題なく生成される.また,直感的には #define マクロ定義の違いが #ifdef の分岐に影響しそうだが,ソースファイルのコンパイル時に,ヘッダファイルの外からマクロ定義を変更しても,正常にコンパイルできた.

生成された .h.gch ファイルが実際に .h ファイルの代わりに使用される条件は微妙.上の記事には,

ポイントは、アプリケーション自体を作成するときと同じgccコマンドラインオプションを使ってプリコンパイル済みヘッダを作成しなければならないという点である。両者のgccコマンドラインオプションが一致しなければ、プリコンパイル済みヘッダは使用できなくなる可能性が高い。

と書いてあるが,こちらで試してみた限り,ヘッダファイルとソースファイルのコンパイルオプションが完全一致しなくてもコンパイル時間が短縮されることがあった.しかし,細かい条件は不明.そもそも,.h.gch ファイルも今のところ正体不明の謎バイナリだし.

追記 6/29

Precompiled Headers - Using the GNU Compiler Collection (GCC)

GCC の info にプリコンパイル済みヘッダが使用される条件が書かれていたが,結局解決に至っていない.というか,最後の条文に「どのオプションは変えてもよくてどのオプションは変えたら駄目かははっきりしない」と「明言」されていた.なんじゃそりゃ.

A precompiled header file can be used only when these conditions apply:

  • Only one precompiled header can be used in a particular compilation.
  • A precompiled header can't be used once the first C token is seen. You can have preprocessor directives before a precompiled header; you can even include a precompiled header from inside another header, so long as there are no C tokens before the #include.
  • The precompiled header file must be produced for the same language as the current compilation. You can't use a C precompiled header for a C++ compilation.
  • The precompiled header file must be produced by the same compiler version and configuration as the current compilation is using. The easiest way to guarantee this is to use the same compiler binary for creating and using precompiled headers.
  • Any macros defined before the precompiled header (including with -D) must either be defined in the same way as when the precompiled header was generated, or must not affect the precompiled header, which usually means that the they don't appear in the precompiled header at all.
  • Certain command-line options must be defined in the same way as when the precompiled header was generated. At present, it's not clear which options are safe to change and which are not; the safest choice is to use exactly the same options when generating and using the precompiled header.