プロジェクトにほとんど違いがないことはわかっていますが、C++ コードに #defined ヘッダー ガードを使用すると仮定すると、どの形式を使用しますか? たとえば、次のヘッダーがあるとしfoo.hpp
ます。
#ifndef __FOO_HPP__
...
#ifndef INCLUDED_FOO_HPP
...
#ifndef SOME_OTHER_FORMAT
大文字の #defines のアイデアには賛成ですが、これらのガードの形式を決めることはできません。
プロジェクトにほとんど違いがないことはわかっていますが、C++ コードに #defined ヘッダー ガードを使用すると仮定すると、どの形式を使用しますか? たとえば、次のヘッダーがあるとしfoo.hpp
ます。
#ifndef __FOO_HPP__
...
#ifndef INCLUDED_FOO_HPP
...
#ifndef SOME_OTHER_FORMAT
大文字の #defines のアイデアには賛成ですが、これらのガードの形式を決めることはできません。
ヘッダー名だけが危険であることが証明されているため、インクルードガードには常に名前空間または相対パスを含めました。
たとえば、コードのどこかに2つのファイルがある大きなプロジェクトがあります
/myproject/module1/misc.h
/myproject/module2/misc.h
したがって、インクルードガードに一貫した命名スキーマを使用すると、両方のファイルで定義されてしまう可能性があり_MISC_HPP__
ます(このようなエラーを見つけるのは非常に面白いです)。
だから私は
MYPROJECT_MODULE1_MISC_H_
MYPROJECT_MODULE2_MISC_H_
これらの名前はかなり長いですが、二重の定義の苦痛と比較すると、それだけの価値があります。
別のオプションとして、コンパイラー/プラットフォームに依存しない場合は、#pragmaを1回探すことができます。
名前の衝突を本当に回避するために、GUIDを使用します。
#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
いつも使っていますINCLUDED_FOO_HPP
ダブルアンダースコアで物事を開始することは予約されているため、ダブルアンダースコアは使用しません。
個人的には、ファイル名FOO_HPPを使用します。GoogleはSRC_ENGINE_FAST_HPPのようなパス全体を使用します。
名前と関数シグネチャの特定のセットは、常に実装用に予約されています。
- 二重下線(_ _)を含む、または下線で始まり、その後に大文字(2.11)が続く各名前は、あらゆる用途のために実装用に予約されています。
- アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。
(17.4.3.1.2/1
)
私はこのフォーマットを好みます:
#ifndef FOO_HPP
#define FOO_HPP
/* ... */
#endif // FOO_HPP
MYLIB_FOO_HPP
であり、名前の競合を回避するのに役立ちます。Visual StudioまたはMicrosoftコンパイラを使用している場合は、プラグマ方式を使用してください
#pragma once
私が使う
#if !defined(FOO_HPP_INCLUDED)
defined
|| が許可されているため、最新の構文を好みます。&& 演算子 (ここでは使用されていませんが)。
また
#ifndef __FOO_HPP__
先頭のアンダースコアが予約されているため、技術的には違法です。
また、次のようなものを常に使用してきました。
#ifndef FOO_HPP
#define FOO_HPP 1
...
#endif
ほとんどの人が言及しているように、実装による内部使用のために C++ 標準によって予約されているため、2 つのアンダースコアをシンボルの先頭に追加しないでください。
ヘッダー インクルードに関する考慮事項については、John Lakos の優れた本「Large Scale C++ Software Design」( Amazon リンク- スクリプト キディ リンク ナチスのためにサニタイズ) を参照してください。
HTH
乾杯、
ロブ
いつも利用しています
#ifndef FOOBAR_CPP
私が自分の時間に対して支払われていて、まだ会社の基準がない場合、私は次のように使用します:
#ifndef path_to_file_h
#define path_to_file_h
小文字の理由は、ファイル名をコピーして貼り付けたり、スラッシュをアンダースコアに置き換えたりするのが簡単だからです。#ifndef の理由は、#define とうまく調和しているため、シンボルが同じであることを簡単に確認できます。ただし、GUID のアイデアは気に入っているので、試してみるかもしれません。
時間の対価が支払われず、コードを公開していないときは、#pragma once
. 他のほとんどの移植性の問題とは異なり、インクルード ガードを後から追加するのは今と同じくらい簡単です。また、コード ベースについて何も知らない人でも実行できます (たとえば、1 年後の私、または私のコードを送った無実のプログラマーなど)。ので、YAGNI が適用されます。
私が使う
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>
また
<FILENAME_IN_ALL_CAPS>_INCLUDED_<YYYYMMDD>
フォルダ階層との同期を維持するのは面倒です(リファクタリングの友)、GUIDは面倒です、日付のサフィックスで十分です。同じ日に同じ名前のファイルを作成する必要がある場合は、
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>a
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>b
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>...
私はファイルパス+ブースト_INCLUDED
サフィックスに加えて、最近広くサポートされている#pragma once
多くのエディター (私にとっては崇高です) では、このためにいくつかのマクロ/スニペットを定義することもできます。
これがあなたのためにそれを行うものです:
<snippet>
<content><![CDATA[
#ifndef ${1:${TM_FILEPATH/(.*\/(include|src))*([^a-zA-Z0-9_]+)*([a-zA-Z0-9_]+)([.])*([a-zA-Z0-9_]+)*/\U$4_$6/ig}_INCLUDED}
#define $1
#pragma once
$0
#endif // $1
]]></content>
<tabTrigger>incguard</tabTrigger>
<description>include guard</description>
</snippet>
それでyourproject/include/yourlib/yourfile.hpp
になるYOURLIB_YOURFILE_HPP_INCLUDED
追加の外部ソース コード スタイル チェッカー ツールを使用すると、この方法でガードの一貫性を簡単に追跡できます。
私は使用する傾向があります:
#ifndef FILE_DATE_H_
(_H_ を _HPP_ などの適切な拡張子に置き換えます)。日付スタンプは、他の方向/ライブラリの他の同じ名前のヘッダーとの衝突を避けるためのものです。
最終的には次のようになります。
#ifndef SOMEFILE_20082411_H_