5

C ++でのオブジェクトの動的配列に対する私の答えから、そしてC ++識別子でアンダースコアを使用することについてのルールは何ですか?:どうやら、大文字で始まり、_その後に大文字が続く名前は、グローバル名前空間で予約されています。

17.4.3.2.1グローバル名[ lib.global.names]

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

  • __二重下線( )を含む、または下線で始まり、その後に大文字(2.11)が続く各名前は、あらゆる用途のために実装用に予約されています。
  • アンダースコアで始まる各名前は、グローバル名前空間で名前として使用するために実装に予約されています。165

165)このような名前は、名前空間::std(17.4.3.1)でも予約されています。

最初の質問に対する私の答えでは、私はこのようなクラスを持っていました

class A
{
 private:
   vector<int> _Ints;
}

コメントでは、_Ints識別子は予約済みの名前であるため、未定義の動作を呼び出すと言われました。ただし、標準の最近のドラフトによれば、メンバー変数の名前検索は、次のルールを使用して行われます。

3.4.3.1クラスメンバー[ class.qual]

修飾IDネストされた名前指定子がクラスを指定する場合、以下にリストされている場合を除いて、ネストされた名前指定子の後に指定された名前がクラス(10.2)のスコープで検索されます。名前は、そのクラスまたはその基本クラスの1つの1つ以上のメンバーを表すものとします。

私にとって、これは、スコープがクラスであるため、メンバー変数をグローバル名前空間の一部にすることはできないことを意味します。

そして今、質問:

メンバー変数はグローバル名前空間にないため、実装の予約名の規則に違反することは決してないという私の理解は正しいですか?私が正しくない場合、誰かが私のルックアップルールの誤解を説明できますか?

4

3 に答える 3

6

_Int最初の規則に明らかに違反しています。「任意の使用」とは、まさにそのとおりの意味です。つまり、定義済みのマクロであったり、コンパイラで特別な動作をトリガーしたり、コンパイラの作成者が望むものであれば何でもかまいません。名前をどこで使用しても問題ありません。使用すると、未定義の動作になります (コンパイラのドキュメントに別段の記載がない限り)。

より一般的には、少なくとも歴史的には、コンパイラはかなり緩いものであり、多くのシステム ヘッダーには伝統的に、単一のアンダースコアで始まり、その後に小文字が続く名前のマクロが含まれていました。これらも避けた方が無難でしょう。linux(歴史的にも、アンダースコアのない名前もありました。名前が になるという問題があったことは知っています1。アンダースコアは見えませんが...これについてできることはあまりありませんが、競合が発生したときに名前を付けます。)

さらに一般的に言えば、一部のフォントではアンダースコアが適切に表示されないため、シンボルの両端ではアンダースコアを避けるのが最善です。

于 2012-03-12T14:38:35.830 に答える
3

アンダースコアで始まり、その後に大文字が続く識別子は、グローバル名前空間だけでなく、あらゆる用途に予約されているという標準状態から引用したルール。したがって、メンバー変数に名前を付けること_Intsはできません。

アンダースコアまたは大文字が続かないアンダースコアで始まる識別子は、グローバル名前空間で予約されています。_intsたとえば、メンバー変数に名前を付けることはできますが_ints、グローバル名前空間にあるグローバル変数に名前を付けることはできません。

于 2012-03-12T14:37:20.073 に答える
1

どうやら _(大文字) はグローバル名前空間で予約されています。

いいえ。どこでも予約されています。17.4.3.2.1 をもう一度読んでください。

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

これは、「グローバル名前空間」についてまったく言及していません (グローバル名前空間は、後続のルールでのみ関連します)。

于 2012-03-12T14:38:08.870 に答える