皆さんはVisual Studioのコンパイラを使用して日本語コメントを使うとプログラムの動作がおかしくなった経験はありませんでしょうか。
私が担当しているプロジェクトでは基本コメントを書く際は英語なのですが、たまに開発途中にメモ書きとして日本語コメントを書く時があります。
するとさっきまで普通に動いていたプログラムが急に意図しない動作をし始めます。
この経験は何度かあって、その都度Google検索で色々調べてみるのですがどうにもそれらしきものがヒットしない。
しかし少し前に試しにTwitterで検索をしてみました。
その結果同様の事象が意外と出てくる。
明確に説明してくれていたのがこちら。
説明しよう。これをUTF-8で保存してVisual C++でコンパイルすると、「可能」のあとの改行が消えて、if(hoge)がコメントアウトされる。解決策は、Shift_JISで保存するか、BOM付きUTF-8にするか、改行をrnにするかしか知らないんだけど……。Microsoft、何とかしてくれ。 https://t.co/WarbKgRBHa
— kusanoさん@がんばらない (@kusano_k) July 20, 2021
ということで、年単位で「とりあえず日本語コメントを書く時は気を付けよう」と軽く流していた疑問が晴れました。
試しに最小再現環境を作ろうと思って以下のようなコードを書いてみたのですが、これだと再現しません。
#include <iostream>
int main() {
std::cout << "Hello World! 1" << std::endl;
// てすと
if (false)
{
std::cout << "Hello World! 2" << std::endl;
}
return 0;
}
if
の中がfalse
なので普通はHello World! 2
は表示されません。それが正しい挙動です。
しかし、先のTwitterの指摘通りであれば日本語コメントの真下にある行が実行されなくなるため、この例で言うとHello World! 2
が表示されることになります。
ここで、// てすと
の部分を// る
とすると現象が再現してHello World! 2
が表示されます。
この動作の違いには明確な理由があり、BOMなしのUTF-8だとShift-JISとして誤って解釈されることに起因するようです。
再現条件として、Twitterの情報の通りならば以下となります。
- Visual Studioのコンパイラを使用する
- ファイルがUTF-8 BOMなしである
- 改行コードがLFである
「てすと」では再現せず、「る」だと再現したように、これらに加えてどの日本語をどのようにコメントに記載するか、も条件として加わるのですが、そこに関してはいまいち理解ができていないのでまた勉強しようと思います。
この辺りの条件に関しては以下のツイートが参考になると思います。
今試したら直ってた。Microsoft偉い!……と思ったら直ってなかった。Microsoftダメ!!!
// 可能
はセーフだけど、
// る
はダメ。じゃあ最後の}が消えて、コンパイル通らないないのでは?と思うが、
// れる
はセーフ。Shift_JISとして見たときに最後が2バイト文字の1バイト目になるかどうかかな。— kusanoさん@がんばらない (@kusano_k) July 20, 2021
ちなみにVisual Studio 2015以降であれば、コマンドラインオプションに/source-charset:utf-8
を指定することで解決するようです。
残念ながら私の担当しているプロジェクトでは諸事情でVisual Studio 2013のコンパイラを使用しているため、この解決策を採用することはできないのですが。
ネットで調べると言うと「ググる」という言葉があったり英語圏では「googling」という言葉があったり、すっかりGoogle検索がスタンダードになっている感がありますが、それだと見つからないこともあるという事例でもありました。
いつからかTwitterで検索するということをするようになったのですが、Googleだけに頼らずに視野を広く持つことが大事ですね。
最近はRedditで検索することもたまにしています。
ということで、スタンダードなGoogle検索でまともに情報が見つからなかったため、同じ事象で悩まされた人がこの記事に辿り着くことを願います。