大抵の 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 を使用することができるようです。
ブックナビゲーション
- 技術情報
- Boost C++ Libraries メモ
- C++と組込み環境
- C++サンプル集
- C++テンプレート集
- C++プログラマのためのC言語入門
- C/C++迷信集
- [迷信] 'A'~'Z' の値は連続している
- [迷信] 0xe-0xe はゼロ
- [迷信] 1 バイトは 8 ビット
- [迷信] 2の累乗による割り算と右シフトは等価
- [迷信] FILE 型は構造体
- [迷信] abs は常に非負の値を返す
- [迷信] argv[0] はプログラム名
- [迷信] char 型は符号付き
- [迷信] double の出力書式は "%lf"
- [迷信] fflush で入力バッファをクリア
- [迷信] free でメモリを開放する
- [迷信] free に NULL を渡すとクラッシュする
- [迷信] gets は単純に fgets に置き換えられる
- [迷信] isalpha 関数の引数は char 型
- [迷信] new に失敗すると NULL が返る。
- [迷信] scanf ではバッファオーバーランを防げない
- [迷信] scanf でキーボードから入力
- [迷信] setjmp マクロの返却値は変数に代入できる
- [迷信] sizeof は定数式
- [迷信] void main(void)
- [迷信] とりあえず memset で初期化
- [迷信] アルゴリズム関数内で関数オブジェクトはコピーされない
- [迷信] オブジェクトの動的生成に失敗するとメモリリークする
- [迷信] コンストラクタから例外を送出してはならない
- [迷信] コンストラクタで自身をゼロクリア
- [迷信] コンパイラはプログラマの心を察してくれる
- [迷信] コンパイルエラーが出るのでアクセス指定子を修正
- [迷信] ソースコード中の即値を全廃せよ
- [迷信] ソースファイルの末尾に }
- [迷信] データ列のソートには qsort 関数を使うべし
- [迷信] プログラムは必ず main から始まる
- [迷信] 一重引用符の中には一文字しか書けない
- [迷信] 今どき int が 16 ビットの処理系なんて無い
- [迷信] 入力データ格納用配列のサイズは BUFSIZ
- [迷信] 割付けたメモリはプログラマが自分で解放しなければならない
- [迷信] 実数型とは浮動小数点型のことである
- [迷信] 引用符で囲んだヘッダ名はカレントディレクトリから探索する
- [迷信] 文字列から整数への変換には atoi
- [迷信] 構造体のタグ名は下線で始める
- [迷信] 構造体はクラスではない
- [迷信] 識別子に使える文字は英数字と下線のみ
- [迷信] 非局所オブジェクトは外部結合
- C99関数・マクロ・前処理スクリプト集
- C言語再入門
- C言語徹底入門
- Drupal メモ
- TOPPERS 情報
- ベターCとしてのC++
- マイコン メモ
- ライブラリ開発入門
- 分割コンパイルをきわめる
- 擬似プロセッサを作る
- 象の卵を探して...
- 車輪の再発明
- 過去の情報


国際文字名についての補足
最近、このページのアクセスが増えてきました。誤解を与えるといけませんので、国際文字名に関して若干補足説明を行いたいと思います。
国際文字名には ISO 10646 文字集合の文字を指定できるわけですが、どんな文字でも指定できるわけではありません。具体的には、0xa0 未満の文字のうち、
'@', '$', '`'以外を指定することはできません。しかし、\uhhhhまたは\Uhhhhhhhh形式ではなく、多バイト文字で指定する場合には特にこれは意識する必要がないでしょう。もうひとつ、国際文字名が現れる文脈には、識別子、文字定数、文字列リテラルがあります。識別子に国際文字名を使う場合はもう少し制約があり、ISO/IEC 14882:2003 では Annex E、ISO/IEC 9899:1999 では Annex D にそれぞれ使用できる文字の一覧が記載されています(日本語版には記載がありません)。
識別子の場合の制約をごく簡単にいえば、記号や数字は使用できないということです。全角スペースももちろんダメです。あと、C と C++ では微妙に使用できる文字が異なります。後から規格化された C の方が、若干使用可能な文字が増えているようです。といっても、
\u00aa ('ª')とか\u00ba ('º')で、日本人がそれらを使う機会はほとんどないように思います。