web-dev-qa-db-ja.com

最初または最後に独自のヘッダーファイルを含めますか?技術的な理由はありますか?

私は私の質問を再訪していました ヘッダー地獄を防ぐにはどうすればよいですか? 、私が言ったコメントに気付いたとき

ヘッダーが独立していることを確認するための優れた手法は、ソースファイルには常に独自のヘッダーが最初に含まれるというルールを設けることです。これは、依存関係のインクルードを実装ファイルからヘッダーファイルに移動する必要がある場合をキャッチします。

私がそれに従うかどうかは定かではありませんが、私が働いてきたすべての場所でその逆がルールであったようです。私はそれについて考えたことも、質問したこともありません。

.Cまたは.CPPファイルが独自のヘッダーファイルを#includeまたは最後に#includeする技術的な理由はありますか、それとも違いはありませんか?

意見ではなく、技術的な理由を探しています。 「最高」の意見は何もありません。他の#includeをリファクタリングまたは追加/削除する際の問題を防ぐのに役立つ可能性のある回答は大歓迎です。

#includeディレクティブは、ソースでの出現順に処理されます。概念的には、#includeが検出されると、そのディレクティブは参照ファイルの内容に置き換えられ、その後、変更されたソースで処理が続行されます(したがって、処理はインクルードファイルからの最初の行から続行されます)。

ソースファイルの最初の#includeディレクティブがそのソースファイルに対応するヘッダーに対するものである場合、他のヘッダーがまだ処理されていないことを確認でき、ヘッダーが一部のヘッダーに依存していないことを証明できます。その前に含まれる他のヘッダー。

それ以外は、使用される前にすべての識別子が宣言されているという制約が満たされている限り、オーダーヘッダーファイルがリストされているCまたはC++コンパイラに何の違いもありません。

使用したヘッダー構造には2つのオプションがあります。

  1. ヘッダーにはヘッダーは含まれません。このアプローチには、ヘッダーが軽いという利点があり、多くの不要なマルチインクルージョンが原因で速度が低下しません。使用がトリッキーであり、変更時に不安定であるため、これは悪いことです。ヘッダーファイルに含めるには、ヘッダーファイルに必要なすべてのインクルードを見つける必要があります。ヘッダーに新しいインクルードが必要な場合は、それを含むすべてのファイルを変更する必要があります。

  2. ヘッダーには、コンパイルに必要なすべてが含まれます。この方法は、必要なヘッダーのみを常に含めることができ、機能することを意味します。 最初にヘッダーを含めることは、この規約が確実に満たされるようにするための単なる方法です。ソースファイルの最初のインクルードの前には何も含まれていないため、このインクルードにより、ヘッダーが他のヘッダーとは独立してコンパイルされることが保証されます。欠点は、コンパイル時間のコストが小さいことです(最新のコンパイラはこれに十分対応できます)。このアプローチはadding追加インクルードに対して安定していますが、インクルードを削除しますヘッダーファイルが原因で、そのヘッダーを含むファイルがコンパイルに失敗することがあります。

3
Jack Aidley