Shift-JISコード文字に 0x5C(エスケープシーケンス) が含まれるときに生じる不具合について
C言語などのプログラミング言語は " \ " や " ¥ " をメタ文字(エスケープシーケンス)として扱います。XMLやHTML,CSVも " \ " や " ¥ " をエスケープシーケンスとして扱うため同様の問題が発生します。
C言語のエスケープシーケンスの例
\n
: 改行文字\0
: nul文字\x1B
: 16進数表記
" \ " , " ¥ " の ASCII文字コード ( UTF-8エンコード ) は 0x5C
です。
一方でShift-JISでは、例えば以下の文字が16bitの中の下位バイトに 0x5C
を含みます。ちなみにShift-JISはプラットフォームに関わりなくビッグエンディアンとなります。したがって 2バイト目 に 0x5C
が出現します。1バイト目にASCII文字と重複するコードを避ける。それがShift-JISの仕掛け(特徴)です。翻って2バイト目にはASCII文字と重複するコードが現れる可能性がある。それが Shift-JIS (2バイト文字コード) と ASCII文字 (1バイト文字コード) が混在する文字コードを扱うときの弱点です。
0x5Cを含む文字の例
文字 | 16進数コード | 意味・用例 |
---|---|---|
— | 0x815C | 半角のダッシュ |
ソ | 0x835C | 全角カタカナのソ |
構 | 0x8D5C | 機構 |
十 | 0x8F5C | 漢数字の十 |
貼 | 0x935C | 下貼、目貼 |
能 | 0x945C | 機能 |
表 | 0x955C | 図表、別表 |
Shift-JISの文字コードに含まれる 0x5c が予想外の影響(不具合)を引き起こす例
1 2 |
func_x(); // x機能 if (mode > 0) { stop_x(); } |
Shift-JISに未対応のコンパイラ(言語処理系)は『能』の2バイト目の0x5Cをエスケープ文字として扱い、行末の改行文字(例えば CR / 0x0D )をエスケープします。
1 |
func_x(); // x機?\?if (mode > 0) { stop_x(); } |
結果として1行目と2行目が連結されて、コンパイラは2行目もコメントアウトとみなします。
文字がエスケープされた後の悪影響はケースバイケースですので十分に注意する必要があります。
C/C++ソースコードにおける0x5c問題の回避策
- Shift-JISを使わない
- コメントを
/* ~ */
形式に統一する - コメントの末尾に句点や全角スペースを挿入する