C++ の予約済み識別子

17.4.3.1 Reserved names [lib.reserved.names] の 17.4.3.1.2 Global names [lib.global.names]:

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore (__) or begins with an underscore followed by an upper case letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace. <>

これの第一項にある (2.11) の意図がわからなくてもんもんと過ごしていたことをおもいだした。昨日の同僚のメールで。

続く 17.4.3.1.3/3 に "Each name having two consecutive underscores (2.11) is ..." とあり、二重下線を含む名前を (2.11) と受けている事実から、第一項の (2.11) は "Each name that ... letter (2.11)" までの全体を受けていると考えられ…なくはない。不自然だけど。

2.11 は Keyword の定義で、その文頭は "The identifiers shown in Table 3 are reserved for use as keywords"。少々強引だけど、直前の 2.10 とあわせて 2.11 は識別子を定義していると考える。 (キーワードは識別子の部分集合であることは、文から読み取れる。)

「名前」は 3 Basic concepts/4 に "A name is a use of an identifier (2.10) that denotes an entity
or label (6.6.4, 6.1)." と定義されている。

で、強引さに目をつぶって訳すと、こんな感じ:
「名前 -- これは (2.11) を見てね -- のうちふたつのアンダースコアを含むものや、アンダースコアで始まり次の文字が大文字のものは、実装がどのように使ってよいものとし予約する」

なお、 C++ 規格のエラッタには、この (2.11) に関する言及を見つけられなかった。

int ::_Reserved; // これは NG

int ::f(void) { // f はグローバルスコープの名前
  char _tmp; // これは OK、 (関数のローカルスコープ)

class ::Class { // Class はグローバルスコープの名前
  int _var; // これも OK。 (クラススコープ)
  char m__c, _Char; // NG。自分のコードでは使えない。
   // コンパイラや標準ライブラリの実装で使うのは OK。