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 つのアンダースコア ( ) を含む名前、
__
またはアンダースコアで始まり、その後に大文字が続く名前 (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
は予約済みです
現在、これらの名前を独自の目的で使用しても問題は発生しない可能性がありますが、その標準の将来のバージョンと競合する可能性があります。
個人的には、識別子をアンダースコアで始めません。私のルールへの新しい追加: どこでも二重下線を使用しないでください。私はほとんど下線を使用しないので簡単です。
この記事の調査を行った後、_t
これは POSIX 標準で予約されているため、識別子を で終わらせることはもうありません。
で終わるすべての識別子に関する規則は、_t
私を大いに驚かせました。それは、明確化と公式の章と節を探しているPOSIX標準(まだわかりません)だと思います。これはGNU libtool manualからのもので、予約済みの名前がリストされています。
CesarB は、POSIX 2004の予約済みシンボルへの次のリンクを提供し、「他の多くの予約済みのプレフィックスとサフィックスが ... そこにある」ことに注意してください。POSIX 2008予約シンボルは、ここで定義されています。 制限は、上記のものよりも多少微妙です。
名前の衝突を避けるための規則は、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 つのアンダースコア _ _ を含む名前、またはアンダースコアの後に大文字が続く名前 (2.12) は、実装用に予約されています。
— アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。
だけでなく:
17.6.3.3.5 ユーザー定義のリテラル接尾辞 [usrlit.suffix]
アンダースコアで始まらないリテラル サフィックス識別子は、将来の標準化のために予約されています。
グローバル名前空間で定義されていない場合、1つのアンダースコアで始まり、その後に小文字が続く名前がOKであると考えない限り、この最後の句は紛らわしいです...
MSDNから:
識別子の先頭での 2 つの連続するアンダースコア文字 ( __ ) の使用、または先頭の 1 つのアンダースコアの後に大文字を使用することは、すべてのスコープで C++ 実装用に予約されています。現在または将来の予約済み識別子と競合する可能性があるため、ファイル スコープを持つ名前の先頭にアンダースコアを 1 つ使用し、その後に小文字を使用することは避けてください。
これは、小文字が続く限り、1 つのアンダースコアをメンバー変数のプレフィックスとして使用できることを意味します。
これは明らかに C++ 標準のセクション 17.4.3.1.2 から取られたものですが、オンラインで完全な標準の元のソースを見つけることができません。
この質問も参照してください。
質問の他の部分については、変数名の最後にアンダースコアを付けて、内部のものと衝突しないようにするのが一般的です。
これは、クラスと名前空間の内部でも行います。これは、1つのルールを覚えるだけでよいためです(「グローバルスコープの名前の末尾、およびその他の場所の名前の先頭」と比較して)。
はい、アンダースコアは識別子のどこでも使用できます。ルールは次のとおりだと思います: 最初の文字は az、AZ、_ のいずれかで、その後の文字は +0-9 です。
アンダースコアのプレフィックスは C コードでは一般的です。1 つのアンダースコアは「プライベート」を意味し、2 つのアンダースコアは通常、コンパイラが使用するために予約されています。