2011-02-01 19 views
16

C++にはどのような名前のガードが含まれていますか?私はこれをたくさん見る傾向があります:名前を付けるガード

#ifndef FOO_H 
#define FOO_H 

// ... 

#endif 

しかし、私はそれは非常に直感的ではないと思います。ファイル名を見ることなく、FOO_Hが何であるか、その名前が何を指しているのかを知ることは困難です。

ベストプラクティスとは何ですか?

+2

(...または、より良い、#pragma multipleとデフォルトの動作も「一度」)#pragma onceを実装あなたはそれらの行を読むことを少し経験します。目と頭脳は '#ifdef blahblah ... 'に慣れていますが、実際には何が確認されているのかはほとんど分かりませんが、それはインクルードガードです。 –

+3

これについては多少の有用な見解があります:http://stackoverflow.com/questions/1744144/adding-an-include-guard-breaks-the-build/1744302#1744302 –

+0

C++開発者は誰でもヘッダガードの認識に慣れている方がいい非常に迅速に。あなたが見ている標準に常に従います。 "ベスト"の習慣(必要なので引用符で囲みます)は、ifndefを最初に置いて、直後に定義し、ファイルの最後でそれを終了することです。私はあなたがこれをできるだけ早く認識することを学ぶことを提案する。 –

答えて

15

私の経験からは、ヘッダーファイルの後にインクルードガードに名前を付けることができますが、名前がすべて大文字であり、ピリオドがアンダースコアに置き換えられます。

したがってtest.hTEST_Hになります。

実際の例としては、クラスヘッダファイルを自動生成するときにこの規則に従うQt Creatorがあります。

+4

すべてのプロジェクトのすべてのファイルとサブディレクトリのない同じディレクトリ内のすべてのライブラリをとにかく保つので、インクルードガード名としてFILENAME_Hを使用するとよいでしょう。 –

+2

これは一般的なプラクティスですがあなたのショップが#defineと他の名前で何をしているかによって、十分ではないかもしれません。 –

1

私は通常FOO_H_INCLUDED_のようなものを使用します。いくつかの(Microsoftの)ヘッダーは、GUIDの文字列表現によく似ていますが、それほど精巧なものは必要としませんでした。

3

FOO_HFOO_H_INCLUDEDに置き換えてください。

1

通常、ファイル名でファイル名を指定するので、各ファイルのコードはコンパイルされて一度だけ追加されます。あなたはFOO_Hをあなたが望むものにすることができましたが、私が今までにコード化したり見たことのほとんどがファイル名を使用していました。 FOO_Hが他の誰かのFOO_Hと競合しないようにするため、それが一意であることを確認してください。

10

google's style guideから直接取得:

すべてのヘッダファイルが複数の混入を防止するために#define ガードを持っている必要があります。 シンボル名の形式は、 にする必要があります。< PROJECT> _ < PATH> _ < FILE> _H_です。 の一意性を保証するには、プロジェクトの ソースツリーのフルパスに基づいて、 にする必要があります。

#ifndef FOO_BAR_BAZ_H_ 
#define FOO_BAR_BAZ_H_ 
... 
#endif // FOO_BAR_BAZ_H_ 

私は自分のプロジェクトでこのスタイルを使用します。たとえば、プロジェクトfooの でファイル のfoo/SRC /バー/ baz.hには、以下のガードを持っている必要があります。

+5

一般的に言えば、私は今まで見たことのない悪化の1つです。私は名前空間に接頭辞を付けます。複数の名前空間に同じ名前のものがある場合は、絶対に必要です。 –

+0

私は理解しようとしてきました。後ろのアンダースコアの後ろには何らかの理由がありますか? – Toby

+1

@トビーちょうどそれを(もっと)ユニークにする...誰かが 'CONFIG_H 'をすでに持っている場合(例えば、インクルードされたライブラリのように)、' CONFIG_H_'を使うことはそれと衝突しません。一部の人々が先頭のアンダースコアを使用するのと同じ理由がありますが、thagsが予約されているため、これらを使用しないでください。 – RastaJedi

1

私はいつもそれを見て、それを最後に追加します。つまり、FOO_H_248です。それは余計な予防策です。とにかくそれを覚えておく必要はないので、それは秘密だという事実。他の人が前に述べたよう

+0

12時間または24時間の時計を使用していますが、現地時間ですか? ;-) – T33C

+5

@ T33C:12? 24?あなたは何について話していますか?それはただの17時間の時計です。それは教皇がその瞬間にどこにいても現地時間です。 –

2

は、非常に一般的な慣例は、アンダースコアに置き換え名の大文字バージョン、およびドットを使用することです:foo.hという - > FOO_H

しかし、これは、との名前の衝突につながることができます単純な名前および/または一般的な名前。このため、非空のVisual C C++のプロジェクトのようないくつかのランダムな文字列、追加でstdafx.hをのような自動生成されたヘッダー:

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS 
#define FOO_H__NsknZfLkajnTFBpHIhKS 
#endif 

http://www.random.org/strings/は、このために便利な乱数生成器です。

ファイルは、いくつかのサブモジュールの一部である、またはその内容は一つの特定の名前空間内に存在する場合も、私はあまりにもガードにそれを追加する傾向があります。#のあなたのヘッダーを含めるコードで

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS 

namespace somecomponent 
{ 
    ... 
} 

#endif 
+4

これらは二重のアンダースコアのために予約された名前です。だからそれを使うのは良い習慣ではありません。 –

4

ルック。

それはのようなものである場合:

#include "mylib/myheader.h" 

mylib/myheader.hすでに一意の名前です。 /と大文字と小文字を置き換えてください。あなたのインクルードパスに同じ名前の相対してパスを含めるには2つのヘッダを持っている場合は_

#define MYLIB_MYHEADER_H 

で、あなたはすでにそのレベルでの衝突を持っています。

16

私は個人的にブーストの推奨に従います。たぶん、これはおそらく、C++ライブラリの中で最も優れたコレクションの一つであり、問​​題はありません。

それはのように行く:

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED 

// include/pet/project/file.hpp 
#ifndef PET_PROJECT_FILE_HPP_INCLUDED 

である:

  • 法的(_[A-Z]することにより、その始まりを注意したり__を含むことはできません)
  • 一意であることが保証
  • を生成しやすいです(インクルードガードとして)(他の場所に2つのファイルがある場合)
  • (あなたが戦いのために台無しにしている INCLUDEDで別のマクロを終了している場合)、何のために使用されないことが保証210

私はGUIDについて読んだが、それらは奇妙に見えます。

そして、明らかに私はしたいのではなく、すべてのコンパイラは名前が多かれ少なかれ直感的かもしれないが、事実が持つということである

+0

個人的には、拡張を追加することは冗長ですが、私は_INCLUDEDが実際に何を表しているか、つまり+1するのが好きです。私の好みは、冗長な_Hを使わないでINCLUDE_GUARD_FOOを使用することです。ヘッダだけにガードを含める必要があります。これはもうちょっとイモになりますが、それは本当に味の問題です。 – cmaster

+0

@ cmaster _Hの追加は、CおよびC++実装の機能(それぞれ.hと.hppファイルを使用)がある場合に役立ちます。 – Squirrel

関連する問題