[迷信] 識別子に使える文字は英数字と下線のみ

大抵の C/C++ の入門書の最初の方には、変数名や関数名などの識別子に使える文字として、アルファベットの大文字・小文字、数字、下線(アンダースコア、アンダーバー)だけが使えると書いていると思います。確かに以前の C の規格はそうでしたし、標準化前の C++ でもそうでした。しかし、現在の C/C++ の標準規格はそうはなっていません。

例えば C の場合、識別子の構文は次のようになっています。

identifier:
      identifier-nondigit
      identifier identifier-nondigit
      identifier digit

identifier-nondigit:
      nondigit
      universal-character-name
      other implementation-defined characters

nondigit: one of
      _ a b c d e f g h i j k l m
      n o p q r s t u v w x y z
      A B C D E F G H I J K L M
      N O P Q R S T U V W X Y Z

digit: one of
      0 1 2 3 4 5 6 7 8 9

C++ でも、other implementation-defined characters が含まれない点を除けば実質的に同じです。つまり、ここで注目すべきなのは、universal-character-name というのが含まれている点です。universal-character-name は、日本語訳すなわち JIS X3010 および JIS X3014 では「国際文字名」と呼んでいます。

国際文字名というのは、ISO 10646 文字集合の文字を 16 進数で直接記述してしまおうという仕様です。例えば、「変数」という名前の変数名を使うには、\u5909\u6570 のように、\u に続けて 4 桁の 16 進数を記述することになります。16 ビットで収まらない場合には、\U00123456 のように、\U に続けて 8 桁の 16 進数を記述します。

使える文字が増えたのはよいことですが、これだけでは何とも非人間的な仕様です。できれば、普通に漢字かな混じりで書きたいところです。C++ では、翻訳フェーズ 1、すなわち三つ組表示(三文字表記)を対応する 1 文字に置き換えるのと同じ段階で、基本ソース文字集合にない文字を対応する国際文字名に変換することが明記されています。一方で、C の規格にはこの記述がありません。

国際文字名の扱いに関しては、明らかに C++ の方が便利そうです。ところが、実際には国際文字名にまともに対応している処理系は皆無か、それに近い状況です。その意味では、規格としては「識別子に使える文字は英数字と下線のみ」というのは正しくありませんが、現実の処理系のことを考えると、少なくとも当面はこの考え方は間違っていません。

ちなみに、Microsoft Visual C++ 2005 では、国際文字名とは少し違う気もしますが、識別子に Unicode を使用することができるようです。