1. ホーム
  2. c++

[解決済み] C++の識別子でアンダースコアを使用する場合のルールについて教えてください。

2022-03-19 12:52:28

質問

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 は予約済み
    • は、それぞれ float と long double の引数に対して操作する対応する関数です。
  • で始まる名前 SIG の後に大文字が続くものは予約されています。
    • を追加信号名として使用します。
  • で始まる名前 SIG_ の後に大文字が続くものは予約されています。
    • 追加のシグナルアクションのため。
  • で始まる名前 str , mem または wcs の後に小文字を続ける場合は予約となります。
    • 文字列および配列の追加関数に使用します。
  • で始まる名前 PRI または SCN の後に任意の小文字を続けるか X は予約済み
    • 追加の書式指定子マクロ用
  • で終わる名前 _t は予約済み
    • を追加型名として使用します。

これらの名前を今すぐ自分の目的のために使っても問題はないかもしれませんが、その規格の将来のバージョンと衝突する可能性があります。


個人的には、識別子をアンダースコアで始めないだけです。私のルールに新しいものが加わりました。私はアンダースコアをほとんど使わないので、これは簡単なことです。

この記事で調べた後、私はもう識別子の末尾を _t これはPOSIX規格で予約されているからです。

で終わる識別子に関するルールは _t には、かなり驚きました。それはPOSIX標準(まだわからない)が明確化と公式な章句を求めているのだと思う。のものです。 GNU libtoolマニュアル 予約名の一覧です。

CesarB からは、以下のリンクが提供されました。 POSIX 2004 予約されたシンボルと、「他の多くの予約された接頭辞や接尾辞がそこにある」ことに注意してください。 その POSIX 2008 予約されたシンボルはここで定義されています。 制限事項は上記のものよりも多少ニュアンスが異なります。