以前、Shift_JISのダメ文字問題を紹介した。
この問題がまた再燃してきた。
というのも当時、UTF-8への移行などの根本的な対策をせずに、
2byte目が0x5C(\相当)になる文字と改行コードの間に適当な文字を加える方法で対策としてしまった。
あくまでも暫定対策のつもりだったが、結局そのまま放置されてしまったのである。
で、いろいろコードを書き換えて、あまり考えずにコメントを入れると、
//コメントの末尾が\相当になってしまい、次の行がコメントの継続行になり消えてしまうと。
だからUTF-8に変換しようぜと言ってたんだけど、
当座の問題はさっきの方法で回避できてしまうから直されなかったと。
で、この話をしていたところで、実は気づいていないだけで他のところでも問題が生じているかもねとなった。
どうやって網羅的に確かめられるかなぁと考えて見たのだが、
テキストエディタのgrep機能をうまく使えばできるかもしれないと。
それでいろいろ模索していたのだがうまくいく方法が見つかった。
今回考えないといけないのはShift_JISの2byte目が\相当で、その次が改行コードである場合である。
普通にASCIIコードの範囲で文字を並べて \+改行コードと並ぶものは意図通りであろうと。
(マクロの継続行でこういう記述は多く存在する)
Shift_JISの1byte目はASCIIの範囲外であることを考えれば、
ASCIIの範囲外1byte→’\’→改行コード(CRまたはLF) の順で並ぶものを探せばよい。
正規表現で’\’は \\ となり、CRまたはLFは[\r\n] と書けばよい。
問題はASCII以外の文字だが、果たしてこれをどう書くか。
普通に考えてもうまく書けないが、\x21 のように書くと文字コード0x21の文字という意味になる。
これを使うことで[\x21-\x7e]でASCIIの図形文字と表現できる。
これと空白を表す文字(スペース, タブ, CR, LF)の集合である\sをあわせると、
ASCIIコードの範囲内で通常使われる文字を全て網羅できる。
これ以外の文字というのは [^\x21-\x7e\s] という表記が出来る。
あとはこれを並べて [^\x21-\x7e\s]\\[\r\n] というパターンになる。
(ただしサクラエディタでは\x21は\x{21}のように書かないと受け付けないので、 [^\x{21}-\x{7e}\s]\\[\r\n] となる)
あとはエンコードを自動判別とかなっているところをLatin1に固定してgrepすれば問題の並びが発見される。
当然、Latin1で解析させてるのでgrep結果の表示は文字化けになるけど。
結果は他にも何箇所かあったが、後ろが空行とか消えても問題が無い行で、
ダメ文字による問題が特に問題にならない場所ばかりだった。
ただ、こういう状況は当然問題なわけで、文字コード変換をするか、
改行前に何か文字を足すか、悪くても後者の対応は早々するのだろう。
ところでコンパイラ側での対策はできないもんなのだろうか。
実は前に使っていたコンパイラではShift_JISであると指定していたようだ。
別件で今使っているコンパイラの説明書を読んでいたのだが、
明確にShift_JISを指定する方法はなさそうだった。
(もしかするとShift_JISが設定できそうな項目はあったけど)
ただし、ASCII範囲外の文字がコメント等に入ること自体はいずれの設定でも問題なく、
UTF-8やEUC-JPのようにASCII範囲外の文字が全てASCII範囲外のコードになる場合は問題なくビルドできる。
このためShift_JISを使わなければ問題ないという結論に至るわけである。
ちなみにUTF-8は文字コードとして明確に指定する機能が存在する。
この機能が必要なのはASCII範囲外の文字・文字列リテラルを使う時だろう。
ワイド文字リテラルというのがあって L’あ’ のように書くと、
wchar_t形に格納できる、’あ’の文字コード(通常はUnicode)を表すことができる。
なお、wchar_tが16byteか32byteかは環境による。
L”表示” のようにワイド文字列リテラルをプログラムの中に書きたい場合は、
UTF-8で記述してUTF-8指定でビルドすれば取り込めるはず。
一方で、それに相当する記述はASCIIの範囲内でも L”\x8868\x793a” のように文字コードを使えば表現できる。
当然そんな使い方はしないわけだし、コメントだけならコンパイラが文字コードを意識する必要性は乏しい。
コメントで問題になるのは行末の\だけと考えてよいと思うので、
Shift_JISでは問題だけど、他は問題なしと言い切ってよさそう。
それも古典的な /*~*/コメントであれば問題なしと言えそうだ。
(Shift_JISの2byteが ‘*’ に相当するコードになることはない)
かといって /*~*/コメントばかり使えというのも現実的ではないわけで、
現代的にはUTF-8を使うのがやっぱり最善の選択肢だと思いますがね。