web-dev-qa-db-ja.com

C ++およびCのヘッダーガード

LearnCpp.com | 1.10 —プリプロセッサの初見Header guardsには、次のコードスニペットがあります。

add.h:

_#include "mymath.h"
int add(int x, int y);
_

減算.h:

_#include "mymath.h"
int subtract(int x, int y);
_

main.cpp:

_#include "add.h"
#include "subtract.h"
_

header guardの実装では、次のように言及されています。

_#ifndef ADD_H
#define ADD_H

// your declarations here

#endif
_
  • 宣言はここにありますか?そして、int main()は_#endif_の後に来るべきですか?
  • __H_を追加するのは慣例ですか、それとも必須のことですか?

ありがとう。

30
Simplicity

FILENAME_Hは規則です。本当に必要な場合は、#ifndef FLUFFY_KITTENSをヘッダーガードとして使用できます(他の場所で定義されていない場合)が、何か他のものの子猫の数など、別の場所で定義した場合、それは厄介なバグになります。

ヘッダーファイルadd.hでは、宣言は文字通り#ifndef#endifの間にあります。

#ifndef ADD_H
#define ADD_H

#include "mymath.h"
int add(int x, int y);

#endif

最後に、int main()をヘッダーファイルに含めることはできません。常に.cppファイルにある必要があります。

クリアするには:

#ifndef ADD_Hは、基本的に「ADD_Hがファイルまたはインクルードファイルで#definedでない場合、#ifndefディレクティブと#endifディレクティブの間でコードをコンパイルする」ことを意味します。したがって、#include "add.h"ファイルで.cppを複数回試行すると、コンパイラはADD_Hがすでに#definedであったものを確認し、#ifndef#endifの間のコードを無視します。ヘッダーガードは、ヘッダーファイルが同じ.cppファイルに複数回含まれることを防ぐだけです。ヘッダーガードは、他の.cppファイルがヘッダーファイルを含むことを妨げません。ただし、すべての.cppファイルには、保護されたヘッダーファイル一度だけを含めることができます。

55
  • 1つの実装(「.cpp」)ファイルの前処理の結果は、変換単位(TU)です。

  • ヘッダーには他のヘッダーを含めることができるため、同じTU内で間接的に複数回ヘッダーを含めることができます。 (mymath.hはこの例です。)

  • 定義は、TUごとに1回のみ発生します。 (一部の定義は複数のTUに存在してはなりません。この場合はわずかに異なり、ここでは説明しません。)

  • ガードが解決する問題は、特定のヘッダーが1つのTU内に複数回含まれている場合に、複数の定義エラーを防ぐことです。

  • インクルードガードは、2番目以降のインクルードがノーオペレーションになるようにヘッダーのコンテンツを「ラップ」することにより機能します。 #ifndef /#defineディレクティブはファイルの最初の2行であり、#endifは最後である必要があります。

  • インクルードガードはヘッダーでのみ使用されます。メイン関数をヘッダーで定義しないでください。実装ファイルに入れてください。

型を定義して関数を宣言するが、ヘッダー自体も必要とするヘッダーがある場合:

#include "other_header.h"

struct Example {};

void f();

インクルードガードで「ラップ」すると、ファイルの完全なコンテンツが得られます。

#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE

#include "other_header.h"

struct Example {};

void f();

#endif

インクルードガードに使用する名前は一意である必要があります。そうしないと、名前が競合すると混乱を招く結果になります。これらの名前は単なるマクロであり、特定のスタイルを強制する言語には何もありません。ただし、通常、プロジェクトの規則には要件があります。 SOなど); この回答 には、適切な基準と概要が記載されている、さまざまなインクルードガードの命名スタイルがあります。

17
Fred Nurk

ヘッダーガードは、ヘッダーを1回だけ含めることを許可します。 (それらが複数回含まれている場合、それらは無視されます。)

使用する名前は重要ではありませんが、あなたが示したような拡張子を含むファイル名を大文字で使用するのが一般的です。

mainは本当に.cppファイルですが、ヘッダーに挿入する場合は、ガード内に配置して、複数回宣言されないようにします。

3
Mehrdad

いいえ、int main()は.cppに入ります。宣言は、ヘッダーに配置する他の要素です。 _Hは規約です。さまざまなヘッダーガード規約を確認できます。

1
Puppy

ヘッダーファイルと定義で宣言を宣言するか、int main()source.cppファイルに含まれています。

_Hは、インクルードガードを使用して誰かがヘッダーファイルをインクルードすることを単に示すためにあります。

MSVC++を使用している場合は、#pragma onceも使用できます

1
cpx