996

C++ では、ローカル変数やパラメーターではなく、メンバー変数であることを示すために、メンバー変数に何らかのプレフィックスを付けて名前を付けるのが一般的です。MFC のバックグラウンドを持っている場合は、おそらくm_foo. 私もmyFoo時々見かけました。

C# (または .NET のみ) では、_foo. これは C++ 標準で許可されていますか?

4

5 に答える 5

916

ルール (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_errhandlingsetjmpva_end

その他の制限が適用される場合があります。たとえば、POSIX 標準では、通常のコードで表示される可能性が高い多くの識別子が予約されています。

  • 大文字で始まる名前のE後に数字または大文字が続く:
    • 追加のエラー コード名に使用できます。
  • 小文字で始まるかisto小文字が続く 名前
    • 追加の文字テストおよび変換機能に使用できます。
  • で始まりLC_、大文字 が続く名前
    • ロケール属性を指定する追加のマクロに使用できます。
  • 既存のすべての数学関数の名前は、接尾辞fまたはlが予約されています
    • float および long double 引数をそれぞれ操作する対応する関数の場合。
  • で始まりSIG、大文字が続く名前は予約されています
    • 追加の信号名。
  • で始まりSIG_、大文字が続く名前は予約されています
    • 追加の信号アクション用。
  • strmem、またはwcs小文字が続く 名前は予約されています
    • 追加の文字列および配列関数用。
  • 小文字で始まる名前、PRIまたはSCN小文字が続く名前、またはX予約さ れている名前
    • 追加の書式指定子マクロ用
  • で終わる名前_tは予約済みです
    • 追加のタイプ名。

現在、これらの名前を独自の目的で使用しても問題は発生しない可能性がありますが、その標準の将来のバージョンと競合する可能性があります。


個人的には、識別子をアンダースコアで始めません。私のルールへの新しい追加: どこでも二重下線を使用しないでください。私はほとんど下線を使用しないので簡単です。

この記事の調査を行った後、_t これは POSIX 標準で予約されているため、識別子を で終わらせることはもうありません。

で終わるすべての識別子に関する規則は、_t私を大いに驚かせました。それは、明確化と公式の章と節を探しているPOSIX標準(まだわかりません)だと思います。これはGNU libtool manualからのもので、予約済みの名前がリストされています。

CesarB は、POSIX 2004の予約済みシンボルへの次のリンクを提供し、「他の多くの予約済みのプレフィックスとサフィックスが ... そこにある」ことに注意してください。POSIX 2008予約シンボルは、ここで定義されています。 制限は、上記のものよりも多少微妙です。

于 2008-10-23T07:08:41.280 に答える
213

名前の衝突を避けるための規則は、C++ 標準 (Stroustrup の本を参照) と C++ の達人 (Sutter など) によって言及されています。

個人ルール

私はケースを扱いたくなかったので、シンプルなルールが欲しかったので、シンプルで正しい個人的なルールをデザインしました:

シンボルに名前を付けるとき、次の場合、コンパイラ/OS/標準ライブラリとの衝突を回避できます。

  • アンダースコアでシンボルを開始しないでください
  • 内部に 2 つの連続するアンダースコアを含むシンボルに名前を付けないでください。

もちろん、コードを一意の名前空間に配置することも、衝突を回避するのに役立ちます (ただし、悪意のあるマクロから保護することはできません)。

いくつかの例

(マクロは C/C++ シンボルのコードを汚染するため、マクロを使用しますが、変数名からクラス名まで何でもかまいません)

#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT

C++0x ドラフトからの抜粋

n3242.pdfファイルから(最終的な標準テキストは似ていると思います):

17.6.3.3.2 グローバル名 [global.names]

名前と関数シグネチャの特定のセットは、常に実装用に予約されています。

— 2 つのアンダースコア _ _ を含む名前、またはアンダースコアの後に大文字が続く名前 (2.12) は、実装用に予約されています。

— アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。

だけでなく:

17.6.3.3.5 ユーザー定義のリテラル接尾辞 [usrlit.suffix]

アンダースコアで始まらないリテラル サフィックス識別子は、将来の標準化のために予約されています。

グローバル名前空間で定義されていない場合、1つのアンダースコアで始まり、その後に小文字が続く名前がOKであると考えない限り、この最後の句は紛らわしいです...

于 2008-10-23T07:27:12.287 に答える
46

MSDNから:

識別子の先頭での 2 つの連続するアンダースコア文字 ( __ ) の使用、または先頭の 1 つのアンダースコアの後に大文字を使用することは、すべてのスコープで C++ 実装用に予約されています。現在または将来の予約済み識別子と競合する可能性があるため、ファイル スコープを持つ名前の先頭にアンダースコアを 1 つ使用し、その後に小文字を使用することは避けてください。

これは、小文字が続く限り、1 つのアンダースコアをメンバー変数のプレフィックスとして使用できることを意味します。

これは明らかに C++ 標準のセクション 17.4.3.1.2 から取られたものですが、オンラインで完全な標準の元のソースを見つけることができません。

この質問も参照してください。

于 2008-10-23T07:06:32.703 に答える
27

質問の他の部分については、変数名の最後にアンダースコアを付けて、内部のものと衝突しないようにするのが一般的です。

これは、クラスと名前空間の内部でも行います。これは、1つのルールを覚えるだけでよいためです(「グローバルスコープの名前の末尾、およびその他の場所の名前の先頭」と比較して)。

于 2008-11-14T20:03:28.710 に答える
1

はい、アンダースコアは識別子のどこでも使用できます。ルールは次のとおりだと思います: 最初の文字は az、AZ、_ のいずれかで、その後の文字は +0-9 です。

アンダースコアのプレフィックスは C コードでは一般的です。1 つのアンダースコアは「プライベート」を意味し、2 つのアンダースコアは通常、コンパイラが使用するために予約されています。

于 2008-10-23T07:05:58.040 に答える