0x5C問題
ASCIIコードでは 0x5C に \ (バックスラッシュ) を割り当てています。
しかしながら JIS X 0201 では ¥ (円記号) を割り当てています。
ちなみに、ISO/IEC 646 では 0x5C は各国自由領域に割り当てています。たとえばKB(韓国語) では ₩ が割り当てられています。したがって JIS X 0201 は ASCIIには準拠していませんが、ISO/IEC 646には準拠していることになります。
C言語などでは 0x5C をエスケープシーケンス(特殊文字)として扱っています。たとえば \n は改行, \t は水平タブ, \0 は NULL です。日本語環境では \n を ¥n と読み替えることが慣例となっています。
Shift JIS
ところがソースコードに Shift JIS を使うとさらに事情が複雑になります。一部のワイド文字(漢字)に 0x5C が含まれています。たとえば 『能』は 0x94, 0x5C, 『表』は 0x95, 0x5C と2バイト目に 0x5C を割り当てています。Shift JISに対応していないCコンパイラが 『能』 や 『表』 の文字コードの2バイト目を エスケープとして扱ったばあいでもコメント文の中に現れるため、多くのケースでは実害がないかコンパイルエラーに倒れて気が付きます。しかし次のようにコメントの後ろの行末にこれらの漢字を書くと発見が難しい不具合に陥ります。
func_x(); // x機能
if (mode > 0) stop_x();
上記のようなC言語のソースコードをShift JISに未対応のコンパイラが処理すると0x5C を見つけて直後の改行文字をエスケープ(≒無効化)します。結果として、ソースコードの解析過程で次の行を連結してしまいます。
func_x(); // x機?\?if (mode > 0) stop_x();
このようにコメントの行末に『能』や『表』など 2バイト目に 0x5C を含むワイド文字を書くと次の行までコメントアウトされる意図せぬ不具合を引き起こすことになります。回避策は、コメントに /* comment */ を使ったり、行末にダミーの空白文字を置く方法が挙げられます。
Unicode
Unicode では \ (バックスラッシュ) に U+005C, ¥ (円記号) に U+00A5 と異なるコードを割り当てています。UTF-8では \ (バックスラッシュ) は 0x5C, UTF-16 では 0x5C, 0x00 または 0x00, 0x5C です。MacのJISキーボードで ¥ (円記号) を叩くと U+00A5 が入力されます。そして \ (バックスラッシュ) を入力するときは Option + ¥ (円記号) を叩きます。UnicodeにおいてもC言語のエスケープ文字は U+005C です。U+00A5では代替できません。このことを知らないと MacOS環境で C言語のソースコードを打ち込むときに戸惑うことになります。 一方 WindowsのJISキーボードで ¥ (円記号) を叩くと Unicode の U+005C, もしくは ASCII (ISO/IEC 646) の 0x5C が入力されます。ただし、多くのWindows標準フォント(グリフ)は U+005C に対して ¥ (円記号) を表示します。Shift-JIS (ISO/IEC 646) 環境からの移行はスムースですが Unicode の U+00A5 (円記号) と見た目で区別することが難しいケースが生じます。
Microsoft IME
Microsoft IME 10.0 にて Unicode を入力したばあい、次の通りになります。
¥ [半] : U+005C
¥[全] : U+FFE5
¥ [環境依存] : U+00A5
古くて新しい 0x5C の問題。稀にハマることがあるので気をつけましょう。