Macでコード書いてVisuao Studioに持ってったら文字コードのせいでエラー頻発
移転しました →
環境に依存しないコードだってことでとりあえずMacとXcodeで開発して、一応動作確認しておくかという段になって初めてVisualStudio2013に持っていったら怪しいコンパイルエラーが頻出してどうにもこうにも困ったことになった。
状況
そのときの状況を僕のTwitterと共に振り返ってみる。
まずVisualStudioのコンパイラのせいだと決めつける。
VisualStudioのコンパイラがバグってる気がする
— 大野浩誠 (@xoyip) August 5, 2014
Updateがあるかどうかを調べ、あったので適用してみる。
昨日付けでUpdate3が出てたのでまずはUpdateをかけて試してみる。これでダメだったら困るなぁ
— 大野浩誠 (@xoyip) August 5, 2014
アップデート待ちの間にもう少し調べてみる。
コンパイルエラーの行番号が実際とずれてたり、どう見てもあるはずのシンボルがないってエラー出したりしてるからきっとバグ。エラーが出るファイルに必ずあるのはfor文なので、for文の構文解析にでも失敗してるんじゃないかな。どーだろ、わからん
— 大野浩誠 (@xoyip) August 5, 2014
アップデートしても結局だめで、日本語コメントの辺りをいじっていたらコンパイルが通ることがわかった。文字コードの警告をそのままにしておくとダメだということだね
これのせいか「 warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。」
— 大野浩誠 (@xoyip) August 5, 2014
日本語コメントの行末に特定の文字があるとコンパイルに失敗する。考えてみれば当たり前だ。疑ってすみません。
— 大野浩誠 (@xoyip) August 5, 2014
原因
Macでコードを書いたので文字コードはUTF-8になっている。このファイルをVisual Studioに開くと、BOMがないために正しく解釈されないらしい。そんな状態で構文解析をするもんだからコンパイルエラーがでるようだ。
BOMというのは、↓こういうもの。
Unicodeの符号化形式で符号化したテキストの先頭につける数バイトのデータのことである。このデータを元にUnicodeで符号化されていることおよび符号化の種類の判別に使用する。
解決法
全てのソースコードにBOM付けてあげればよい。Visual Studioで「名前をつけて保存」→「エンコード付きで保存」でもBOMはつくらしいが、ファイル数が多いとそんなことはやってられない。
そこでnkf
コマンドを使い、一括処理することにする。nkfでは以下のコマンドでBOMの付与ができる。
% nkf --overwrite --oc=UTF-8-BOM filepath
ソースコードのルートディレクトリからfind
コマンドと組み合わせて使えば一括処理が可能だ。
例えば、.h
、.c
、.cpp
ファイルを変換するならこうすればいい(3行に分けずにできそうだけど、そこまでがんばることはない)。
% find . -name "*.h" -exec nkf --overwrite --oc=UTF-8-BOM {} \; % find . -name "*.c" -exec nkf --overwrite --oc=UTF-8-BOM {} \; % find . -name "*.cpp" -exec nkf --overwrite --oc=UTF-8-BOM {} \;
これでVisual Studioで警告もでなくなるし、コンパイルエラーもなくなる。よかった。