問題
タイトルのとおり。オプションに与えているのは-Wall
のみのはずだが、何故か-Wall
では出るはずのない警告が大量に発せられるのだ。
警告の内容は、C++98と互換性のないコードだとか、コンマ演算子の使い方に文句をつけられたりとか、static変数にいちゃもんつけてきたりとか、とにかく意味不明なものばかりである。これは何かというと、Clangに-Weverything
というオプションを与えたときに出てくるものだ。
-Weverything
はコンパイル時にすべての警告を出すオプションである。-Wall
と何が違うのか、と思われるかもしれないが、Clangの-Wall
は実はすべての警告を出すわけではない。どうも全警告のうち半分くらいしか有効にならないらしい。
-Wall
では出されない警告を出させるためのオプションとして、-Wextra
や-Weverything
がある。通常は-Wall
に加えて-Wextra
を指定して、より詳細な警告を出力させる場合が多いらしい。
では-Weverything
は使わないのか、というと、一般に使われないし、そもそもClang開発者達でさえ「使うな」と言っている。よほど酔狂であるか、特別な理由がない限り、使わなくて良い。
解決法
結論から言えば、-Wall
を-W4
に変更することで一応は直った。ただしこれはclang-clの場合の対症療法みたいなものである。
Visual StudioがClangと呼んでいるのは、Windows用実装であるclang-clのことだ。これはClangと概ね互換のビルドツールなのだが、clang-clではどうやら-Wall
オプションを与えると自動的に-Weverything
も有効になってしまうようだ。……え?なんで?何故そこの仕様を変えてしまうの?
ではどうするのかと言うと、-W4
を使えばいい。clang-clにおける-W4
は一般的なClangの-Wall -Wextra
と同等の意味である。ごめんちょっと意味分かんない。
macOS上のClangなどでビルドする場合は-Wall -Wextra
とすべきなので、Windowsの場合だけオプションを変えなければならないという度し難い仕様になっている。CMakeを用いる場合、MSVCかClangか、ではなく、Windowsかそうでないかによってオプションを切り替えろということなのだろうか。どうしてこんなのがまかり通っているのだろうか。怒っていい?
参考:https://clang.llvm.org/docs/UsersManual.html#clang-cl
余談
最近のVisual Studioはクロスプラットフォーム開発機能が充実しており、CMakeを用いたビルドに対応したり、Windows Subsystem for Linux(WSL)を使って仮想Linux上でGCCを用いてビルドできたり、Clang互換のビルドツールを使ったりできるようになっている。これがなかなかに便利で、今までMSVC以外の環境に広げることに抵抗があった私もCMakeによるクロスプラットフォーム開発に着手している。 しかし今回のClangの問題が発覚してちょっと気落ちしてしまった。オプションまで含めて完全互換にしてくれないものだろうか。……まあWSL上でClangを使う、MinGWを利用するという選択肢も残されているのだが。