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

大抵の 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 を使用することができるようです。

国際文字名についての補足

最近、このページのアクセスが増えてきました。誤解を与えるといけませんので、国際文字名に関して若干補足説明を行いたいと思います。

国際文字名には ISO 10646 文字集合の文字を指定できるわけですが、どんな文字でも指定できるわけではありません。具体的には、0xa0 未満の文字のうち、'@', '$', '`' 以外を指定することはできません。しかし、\uhhhh または \Uhhhhhhhh 形式ではなく、多バイト文字で指定する場合には特にこれは意識する必要がないでしょう。

もうひとつ、国際文字名が現れる文脈には、識別子、文字定数、文字列リテラルがあります。識別子に国際文字名を使う場合はもう少し制約があり、ISO/IEC 14882:2003 では Annex E、ISO/IEC 9899:1999 では Annex D にそれぞれ使用できる文字の一覧が記載されています(日本語版には記載がありません)。

識別子の場合の制約をごく簡単にいえば、記号や数字は使用できないということです。全角スペースももちろんダメです。あと、C と C++ では微妙に使用できる文字が異なります。後から規格化された C の方が、若干使用可能な文字が増えているようです。といっても、\u00aa ('ª') とか \u00ba ('º') で、日本人がそれらを使う機会はほとんどないように思います。

このエントリーを含むはてなブックマーク