C ++では、メンバー変数にローカル変数やパラメーターではなく、メンバー変数であることを示すために、何らかの接頭辞を付けてメンバー変数に名前を付けるのが一般的です。MFCのバックグラウンドを持っている場合は、おそらくを使用しますm_foo
。myFoo
たまに見たこともあります。
C#(またはおそらく.NET)は、のように、アンダースコアのみの使用を推奨しているよう_foo
です。これはC ++標準で許可されていますか?
C ++では、メンバー変数にローカル変数やパラメーターではなく、メンバー変数であることを示すために、何らかの接頭辞を付けてメンバー変数に名前を付けるのが一般的です。MFCのバックグラウンドを持っている場合は、おそらくを使用しますm_foo
。myFoo
たまに見たこともあります。
C#(またはおそらく.NET)は、のように、アンダースコアのみの使用を推奨しているよう_foo
です。これはC ++標準で許可されていますか?
回答:
ルール(C ++ 11では変更されていません):
std
ネームスペースのすべてが予約されています。(ただし、テンプレートの特殊化を追加することはできます。)2003 C ++標準から:
17.4.3.1.2グローバル名[lib.global.names]
名前と関数シグネチャの特定のセットは、常に実装に予約されています。
- 二重下線(
__
)を含むか、下線で始まり、その後に大文字(2.11)が続く名前は、実装用に予約されています。- アンダースコアで始まる各名前は、グローバル名前空間の名前として使用するために実装で予約されています。165
165)そのような名前は名前空間でも予約されています
::std
(17.4.3.1)。
C ++はC標準(1.1 / 2、C ++ 03)に基づいており、C99は規範的な参照(1.2 / 1、C ++ 03)であるため、1999 C標準から次のように適用されます。
7.1.3予約済み識別子
各ヘッダーは、関連する副次句にリストされているすべての識別子を宣言または定義し、オプションで、関連する将来のライブラリー指示副次句にリストされている識別子と、常に使用またはファイルスコープ識別子として使用するために予約されている識別子を宣言または定義します。
- アンダースコアで始まり、大文字または別のアンダースコアで始まるすべての識別子は、常に使用のために予約されています。
- アンダースコアで始まるすべての識別子は、通常の名前空間とタグ名前空間の両方でファイルスコープを持つ識別子として使用するために常に予約されています。
- 以下の副節(将来のライブラリーの指示を含む)の各マクロ名は、関連するヘッダーが含まれている場合に、指定されたとおりに使用するために予約されています。特に明記されていない限り(7.1.4を参照)。
- 以下の副節(将来のライブラリーの指示を含む)のいずれかに外部リンケージがあるすべての識別子は、外部リンケージがある識別子として使用するために常に予約されています。154
- 次の副節(将来のライブラリの指示を含む)のいずれかにリストされたファイルスコープを持つ各識別子は、マクロ名として、および関連するヘッダーが含まれている場合は同じ名前空間内のファイルスコープを持つ識別子として使用するために予約されています。
他の識別子は予約されていません。プログラムが予約されているコンテキストで識別子を宣言または定義している場合(7.1.4で許可されている場合を除く)、または予約されている識別子をマクロ名として定義している場合の動作は未定義です。
プログラムが
#undef
上記の最初のグループの識別子のマクロ定義を(を使用して)削除した場合の動作は未定義です。154)外部結合を持つ予約識別子のリストは、
errno
、math_errhandling
、setjmp
、およびva_end
。
その他の制限が適用される場合があります。たとえば、POSIX標準では、通常のコードで表示される可能性が高い多くの識別子が予約されています。
E
大文字で始まる名前は、数字または大文字の後に続きます。
is
またはto
小文字が続きます
LC_
大文字
で始まる名前f
またはl
予約されている
すべての既存の数学関数の名前SIG
大文字で始まる名前は予約されています
SIG_
大文字で始まる名前は予約されています
str
、mem
またはwcs
小文字が続くが予約されています
PRI
またはSCN
後に続く名前、またはX
予約されている
名前_t
は予約されています
現時点でこれらの名前を独自の目的で使用しても問題は発生しない可能性がありますが、その標準の将来のバージョンと競合する可能性があります。
個人的には、識別子をアンダースコアで始めないでください。ルールへの新たな追加:アンダースコアを2つ使用しないでください。これは、アンダースコアをほとんど使用しないため簡単です。
この記事を調査した後、識別子が_t
POSIX標準で予約されているため、識別子で終わることはもうありません。
で終わる識別子に関する規則は、_t
私をとても驚かせました。私はそれがPOSIX標準(まだ定かではありません)だと思います。これは、GNU libtoolマニュアルからのもので、予約済みの名前がリストされています。
CesarBは、POSIX 2004の予約済みシンボルおよびメモへの次のリンクを提供し、「他の多くの予約済みの接頭辞および接尾辞...がそこにある」と注記しています。ここでは、 POSIX 2008の予約済みシンボルが定義されています。制限は、上記のものよりも多少微妙です。
_Bool
を言って_Imaginary
C ++に存在しないのですか?C ++言語は、Cへの「編集」に関してではなく、明示的に定義されています。そうでない場合、標準ははるかに短くなる可能性があります。
名前の衝突を回避するための規則は、C ++標準(Stroustrupの本を参照)にあり、C ++の教祖(Sutterなど)によって言及されています。
私はケースを扱いたくなかったし、単純なルールが欲しかったので、私はシンプルで正しい両方の個人的なものを設計しました:
シンボルに名前を付ける場合、以下の場合、コンパイラ/ OS /標準ライブラリとの衝突を回避できます。
もちろん、コードを一意の名前空間に配置すると、衝突も回避できます(ただし、悪質なマクロからは保護されません)。
(マクロはC / C ++シンボルのコードを汚染するため、マクロを使用しますが、変数名からクラス名まで何でもかまいません)
#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT
n3242.pdfファイルから(最終的な標準テキストは同様であることを期待しています):
17.6.3.3.2グローバル名[global.names]
名前と関数シグネチャの特定のセットは、常に実装に予約されています。
—二重アンダースコア_ _を含む、またはアンダースコアで始まり、その後に大文字(2.12)が続く名前は、実装用に予約されています。
—アンダースコアで始まる各名前は、グローバル名前空間の名前として使用するために実装に予約されています。
だけでなく:
17.6.3.3.5ユーザー定義のリテラルサフィックス[usrlit.suffix]
アンダースコアで始まらないリテラルサフィックス識別子は、将来の標準化のために予約されています。
この最後の句は、1つのアンダースコアで始まり、その後に小文字が続く名前がグローバル名前空間で定義されていない場合は Okであると考えない限り、混乱を招きます...
__WRONG_AGAIN__
2つの連続したアンダースコア(最初に2つ、最後に2つ)が含まれているため、これは標準では間違っています。
WRONG__WRONG
2つの連続したアンダースコア(中央に2つ)が含まれているため、これは標準的に間違っています
__attribute__
、GCCの場合)キーワードと衝突する可能性があるため、これだけでは不十分です。
1234567L
またはのようなリテラル値に適用されます4.0f
。IIRCこれはohttp://en.cppreference.com/w/cpp/language/user_literalを参照
Why is there any problem of having two consecutive underscores in the middle according to the standard?
標準はそれらが予約されていると言うので。これはスタイルの良し悪しに関するアドバイスではありません。それは標準からの決定です。なぜ彼らはこれを決めたのですか?最初のコンパイラは、標準化の前にそのような規則を非公式に使用していたと思います。
MSDNから:
識別子の先頭に2つの連続するアンダースコア文字(__)を使用するか、先頭のアンダースコアの後に大文字を1つ使用することは、すべてのスコープのC ++実装用に予約されています。現在または将来の予約済み識別子と競合する可能性があるため、ファイルスコープの名前には、先頭のアンダースコアの後に小文字を続けて使用しないでください。
つまり、小文字が続く限り、単一のアンダースコアをメンバー変数の接頭辞として使用できます。
これは明らかにC ++標準のセクション17.4.3.1.2から取られていますが、完全な標準の元のソースをオンラインで見つけることができません。
この質問も参照してください。