1つの関数または小さなクラスを使用できるようにするために、大きなサードパーティファイルに#includeを作成する必要があることに気付くことがあります。これがなくなったことを知っているので、コンパイル時間が長くなります。その1つの関数が必要な場合は、ファイル全体をコンパイルします。これを回避し、全体を書き直さずに必要な関数を1つだけ含める方法はありますか?
4 に答える
いくつかのオプションがあります:
- ヘッダーを含めるだけです。実際、コンパイル時間はそれほど長くなりません。
- サードパーティのヘッダープロバイダーに苦情を申し立てます。より小さく、よりモジュール式のヘッダーを出荷するように伝えます。
- ヘッダーを含めないでください。ただし、
extern
気になる単一の関数として宣言してください。extern int GetMeaningOfLife(int mice);
ヘッダーの一部だけをコンパイルすることはできません。そのサードパーティがヘッダーに多くのコードをプルさせている場合、それについてできることは何もありません。私が考えることができる最善の解決策は、プリコンパイル済みヘッダーを使用することです。これらのヘッダーは一度だけ完全にコンパイルされるため、コンパイルのオーバーヘッドの一部を排除する必要があります。別のオプションは、他の変換ユニットにヘッダーが含まれている場合、クラスの宣言を含める代わりに、クラスの前方宣言を使用することです。ただし、これでは、これらのクラスをポインタとしてのみ使用できます。
ヘッダーを含めるのではなく、単に独自の前方宣言を作成することが合理的な場合があります。ただし、Thingの定義を担当していない場合は、定義が変更され、前方宣言を更新する必要があるという問題が発生する可能性があります。
たとえば、一部のBoostライブラリは、#includesを回避するために、標準ライブラリでいくつかのことを前方宣言しようとしました。最近、libc ++はインライン名前空間を使用しているため、標準ライブラリのlibc ++実装で問題が発生しました。そのため、単純な前方宣言はlibc++では機能しません。実際、標準ライブラリの実装は、標準に準拠するさまざまなことを実行できますが、さまざまな実装で機能する宣言を破棄する可能性があります。
したがって、手動の前方宣言は壊れやすく、移植性がない可能性がありますが、うまくいく可能性があります。
もう1つのオプションは、プリコンパイル済みヘッダーを使用することです。これにより、ヘッダーを含めるために必要な処理を削減できます。たとえば、標準ライブラリのすべてのヘッダーを含めるスクラッチプロジェクトがあります。プリコンパイル済みヘッダーがないと、空のプログラムをコンパイルするのに数秒かかります。プリコンパイル済みヘッダーを使用すると、空のプログラムはほんの一瞬で完了します。
コンパイラがプリコンパイル済みヘッダーをどのように処理するかを確認する必要があります。たとえば、Gccとclangは、-x c++-headerまたは-xc-headerを使用してヘッダーファイルを処理するときに、プリコンパイル済みヘッダーを生成します。次に、-includeフラグを使用してファイルをインクルードすると、コンパイラーはそのヘッダーのプリコンパイル済みバージョンを検索し(コンパイラー固有の命名規則を使用)、代わりにそれをインクルードする場合があります。
$ cateverything.h
#include <iostream>
$ cat main.cpp
int main() { std::cout << "Hello, World!\n"; }
$ clang ++ -xc++-ヘッダーeverything.h-oeverything.h.pch
$ clang ++ main.cpp -includeeverything.h
$ ./a.out
こんにちは世界
Clangは.pchを検索し、gccは.gchを検索します
ヘッダーによってコンパイル時間が大幅に増加することはありません。何が入っているかによります。不要なものを編集することは確かに可能ですが、お勧めしません。これはエラーが発生しやすく、通常、ごくわずかな投資回収のために多大な労力を要します。ヘッダーにはガードが含まれていますか?そうでない場合、コンパイルが遅くなる場合は、それらを追加することを検討してください。