6

この素晴らしい記事(プリコンパイル済みヘッダーのケアとフィード) を読んだ後、これらが実際にどのように機能するかについて疑問が生じました。より具体的には、次のシナリオでプリコンパイル済みヘッダーの再構築をトリガーする必要があることをどのように知ることができますか:

  • #define.cpp ファイルの 1 つに、プリコンパイル済みヘッダーに既に含まれている一部のヘッダーをプリプロセッサが解釈する方法を変更することにしました。
  • #defineプリコンパイル済みヘッダーに既に含まれているヘッダーをプリプロセッサが解釈する方法を変更する特定のプリプロセッサ ディレクティブである .cpp ファイルの 1 つに別のヘッダーを含めます。
  • #includeさらに悪いことに、特定のヘッダーが他のヘッダーである場合、前の問題が再帰的に発生する可能性があります。

プリコンパイル済みヘッダーを使用する場合、.cpp ファイルに含まれるヘッダーの数を 1 つに制限し、.cpp ファイルに何も含めないなど、特定の制限のあるコーディング スタイルを適用する必要があり#defineますか?

Microsoft のコンパイラは、(MS 固有の voodoo を適用することによって) プリコンパイルされたヘッダーでおそらくまともな仕事をしますが、私の知る限り、すべての配管を行うはずの/Ycand/Yuオプションを提供するため、GCC の場合、これは機能には Makefile で多くの手作業と創造性が必要であり、プリコンパイル済みヘッダーを使用することのすべての落とし穴に対処することになっているテンプレートを見つけることができませんでした。

たとえば、いくつかのライブラリをビルドするプロジェクトがある場合、変更のたびにそれらすべてを再ビルドしないようにするために、現在のライブラリによって d されたヘッダーの 1 つが変更されたかどうかを検出するために Makefile でいくつかの本当にかわいいsedトリック#includeを使用する必要があります。 (または#include変更されたヘッダー)。ビルドスクリプトが必要なたびにヘッダーを再構築するために、事前に構築されたヘッダーが実際に意味する複雑さについて考えるのさえ怖いです。

4

1 に答える 1

15

現在の GCC (つまり 4.7) とその以前のバージョンは、アプリケーションに単一の共通ヘッダーがあり、その単一のヘッダー (すべてのシステムのヘッダーとライブラリ固有のヘッダーが順番に含まれている必要がある) がある場合にのみ、プリコンパイル済みヘッダーでうまく動作します。アプリケーションによって) は、アプリケーションのすべてのソースによって-d (ソースの最初の非コメント語彙素として) です。#include

したがって、コマンド ラインで同じ前処理オプション (つまりまたはまたは) で開始する単一 yourapp.hの すべてのソース ファイル (つまり、すべてのコンパイル ユニット) を用意する必要があります。通常、そのヘッダー ファイルは、システム ヘッダー (または GTK または Qt のヘッダー) など、他の多くのファイル (または [C++ の場合] またはなど)を-ingします。yourapp #include "yourapp.h"-D-I-Uyouapp.h#include<stdlib.h><sys/poll.h><algorithm><gtk/gtk.h><QtGui>

これは、何が含まれているかを知る-Hための便利なオプションであることを思い出してください。gcc

必要に応じて、ソース ファイルに追加の#include after #include "yourapp.h"が含まれる場合があります。

[単一の] プリコンパイル済みヘッダーが GCC によってインクルードされた後、もちろん#define、マクロ、#include一部のプリコンパイルされていないヘッダー、#ifdefなどを使用して条件付きコンパイルを実行できます。ただし、その前処理は「プリコンパイル」されません!

これはあなたのニーズや習慣に合わないかもしれません。

何人かの人々 (特に Google、特に Diego Novillo) は状況を改善するためにPreParsed Header (pph) ブランチに取り組んでいますが、現在の GCC トランクはまだその作業を行っていません。

GCC のその動作に関する説明は、前処理されたヘッダーは本質的に GCC ヒープ全体の永続的なシリアル化されたチェックポイントであるということです ( GCC および GTY を介した GCC 内のメモリ管理gengtypeに関連しています)。gccそのチェックポイントが設定されたヒープは、が初期の空の状態にある場合にのみロードできます。gcc何かが(実際にcc1またはに)認識されるとすぐにcc1plus、プリコンパイル済みヘッダー ファイルをロードできなく*.h.gchなり、テキスト ヘッダー ファイルの解析に戻ります*.h


追記(2014年11月以降)

GCC 4.9でさえ、単一のプリコンパイル済みヘッダーが必要です。Diego Novilloらによる事前解析済みヘッダーの取り組み。放棄されました。

C++ 標準の将来のバージョン ( C++14以降) では、モジュール メカニズムが定義される可能性があります。たとえば、 n4047提案とC++20標準を参照してください。

(追加の補遺、2020 年夏) これは、いくつかの静的アナライザーオプションが存在するGCC-10にも当てはまります。Clang 静的アナライザーこのドラフトレポートも参照してください。Frama-C の使用を検討してください。

于 2012-09-15T14:04:44.540 に答える