[C++] GCC/Clang/VisualStudio の警告をまとめているので紹介

公開:2020/09/25
更新:2020/10/03
20 min読了の目安(約18600字TECH技術記事

はじめに

タイトルの通りではありますが、GCC/Clang/VisualStudio の各コンパイラーが出す C++ の警告をまとめています。
この記事はまとめているリポジトリの紹介です。
srz-zumix/awesome-cpp-warning: c++ warning correspondence table (Clang/GCC and Visual Studio)

個人的に欲しいなと思い、それくらい誰かまとめてるんじゃないかと WEB 検索してもなかなか見つからなかったので自分で作り始めました。
書き始めたものの結構(いやかなり?)大変だということがわかったので、今話題の Zenn で紹介して手伝ってもらえたら…と思い書きました。

なぜ必要か

  • マルチプラットフォーム開発で Clang と Visual Studio(VC++)の 2 つを使っている
  • 警告を 0 にしたい(現状 0 じゃない)
  • 対応した警告は基本的に as error にしている
  • 片方のコンパイラでしか出ない警告があり開発者を困らせている(自分の環境ではビルド通ったのに😠)
  • Clang の警告に対応する VC++ の警告が探しにくい

警告を 0 にするルール(規約や CI)を設定しているプロジェクトは多いと思うのですが、
複数のコンパイラを使っていてると、エラー・警告の形態が異なっていて困ります。
片方だけしか警告・エラーにされない状況を極力減らしたいため、このようなものを作り始めました。

なぜ大変か

  • 再現コードの作成
    • 警告の説明からコードを生成するのが少し手間
    • Visual Studio の警告ドキュメントにはたまにサンプルコードがあるが、再現しない場合がある
    • プロジェクトで実際に発生した警告を都度調査する方法であれば再現コードを得られるが、最小コードでないのが面倒
  • デフォルト無効な警告
    • GCC に -Weverything や /Wall 相当のオプションが欲しい
  • Visual Studio の警告は C や C++/CLI も混在している
  • コンパイラのバージョンを考慮し始めるととてもつらい
    • 特定バージョン以降に追加・削除された警告をどうする?
    • C++ のバージョンどうする?
    • MS 拡張/GNU 拡張どうする?

調査方法

現状コンパイラバージョンとかどうするか決めてないので HEAD(最新バージョン)で調査してます

基本的にはオンラインコンパイラーを利用して再現調査をします。
GCC/Clang の調査には Wandbox を利用させていただいてます。
VC++ の調査には Compiler Explorer を利用させていただいてます。

Visual Studio の警告ドキュメントから

警告ドキュメントに記載されているものを1つ1つオンラインコンパイラーで調査します。
サンプルコードがあるもので GCC/Clang で警告の出るものであれば問題ないのですが、警告が出ないものは VC++ の方でも再現調査をします。
サンプルコードがないものは、文章から警告が出るであろうコードを推測して最小コードを書いてみます。

そのようにして書いたものが以下になります。
https://github.com/srz-zumix/awesome-cpp-warning/blob/master/VCLIST.md

こちらは VC++ -> GCC/Clang の対応表になります。
VC++ をベースにした対応表だと VC++ 固有の警告が多すぎて見づらいので、こちらは参考資料とし、README の方に GCC/Clang をベースとした対応表を書いてます。

ひとまず掲載されている警告はリストアップ済み。
サンプルコードがあるものは GCC/Clang の調査済み。(ただし漏れや誤りがある可能性あり)
C や C++/CLI のみの警告や MS 拡張関連の警告っぽいなと思ったのはスキップしてます。
(リストアップするだけでも面倒くさかったのでここで力尽きた。実利用中に遭遇した警告から最小コード作る方法で今後は埋めていこうかと思ってます。)

Clang の警告ドキュメントから

Clang も Diagnostic flags in Clang — Clang 12 documentation に警告がまとまっているのでそちらから再現コードを書いて Compiler Explorer で VC++ の警告を調べることができます。
ただし、こちらにはサンプルコードはないので文章から推測して最小コードを作る必要があります。
(こちらは着手し始めたくらいです)

実際に遭遇した警告から

この方法が一番簡単かもしれないです。
再現コードも用意しやすいですし、実際に出会うことのないようなコーナーケースの警告対応表よりも有益です。
(ただし、網羅性は低いので対応表の完成のためにはドキュメントからの調査も必須になると思います。)

大きなプロジェクトの場合、最小コードを作るのが難しい場合もあると思いますが、対応する警告を見つけることはできると思うので表は埋められそうです。

今後

すこしずつ表を育てていこうと思いっています。
もちろん Pull Request 大歓迎です。

警告対応表

最後に、リポジトリに掲載している対応表の一部をこちらにも貼り付けておきます。

この対応表は GitHub リポジトリからコピーしたものです。最新版はリポジトリを確認してください。

GCC/Clang の警告グループは未対応。-Wall や -Wextra などが入る予定

警告対応表
GCC Group GCC Warn Clang Group Clang Warn VC Group VC Warn
warning -Wmacro-redefined /W1 C4005
-Wcomment -Wcomment /W1 C4010
-Wsign-compare -Wsign-compare /W3 C4018, C4287
-Wsign-compare -Wsign-compare /W4 C4388, C4389
-Wextra-semi-stmt /W4 C4019
- -Wswitch-enum - -Wswitch-enum /W4 C4061
-Wswitch -Wswitch /W4 C4062
-Wswitch -Wswitch C4063
-Wendif-labels -Wextra-tokens /W1 C4067
-Wunknown-pragmas -Wunknown-pragmas /W1 C4068
-Wmismatched-tags /W2 C4099
-Wunused-parameter -Wunused-parameter /W4 C4100
-Wunused-variable -Wunused-variable /W3 C4101
-Wunused-variable -Wunused-variable /W4 C4189
-Wunused-label -Wunused-label /W3 C4102
-Wpragma-pack /W1 C4103
-pedantic warning -pedantic -Wgnu-zero-line-directive /W1,4 C4112
-Wduplicate-decl-specifier /W1 C4114, C4141
-Wbuiltin-macro-redefined -Wbuiltin-macro-redefined /W1 C4117
warning -Wunknown-escape-sequence /W1 C4129
-Waddress -Wstring-compare /W4 C4130
-Wswitch-bool /W1 C4144, C4145
-Wdelete-incomplete -Wdelete-incomplete /W2 C4150
-Wreturn-local-addr -Wreturn-stack-address /W1 C4172
-Wnarrowing error -Wc++11-narrowing /W1 C4178, C4838
-Wignored-qualifiers /W1 C4180
-Wignored-qualifiers /W3 C4197
-Wreturn-type-c-linkage /W1 C4190
-pedantic -Wpedantic -pedantic -Wzero-length-array /W2,4 C4200
-pedantic -Wpedantic -pedantic -Wgnu-anonymous-struct /W4 C4201
- -Wconversion - -Wimplicit-int-conversion /W4 C4242
- -Wfloat-conversion - -Wfloat-conversion /W2 C4244
- -Wconversion - -Wconversion /W3,4 C4244
- -Wsign-conversion - -Wsign-conversion /W2 C4308
- -Wsign-conversion - -Wsign-conversion /W4 C4245, C4365
- -Woverloaded-virtual -Woverloaded-virtual /W4 C4263
- -Wnon-virtual-dtor - -Wnon-virtual-dtor /W3 C4265
- -Wnon-virtual-dtor - -Wnon-virtual-dtor C5204
- -Wconversion - -Wshorten-64-to-32 /W3 C4267
warning -Wexceptions /W1 C4286
-Wshift-count-overflow -Wshift-count-overflow /W1 C4293
-Wtype-limits -Wtautological-unsigned-zero-compare /W4 C4296
- -Wold-style-cast - -Wold-style-cast C4303
- -Wfloat-conversion - -Wimplicit-float-conversion /W1 C4305
-Woverflow -Winteger-overflow /W2 C4307
- -Wconversion -Wconstant-conversion /W2 C4309
-Wint-to-void-pointer-cast -Wint-to-void-pointer-cast /W1 C4312
-Wformat -Wformat /W1 C4313, C4473, C4477
-Wformat -Wformat /W3 C4475, C4476
-Wformat-extra-args -Wformat-extra-args /W1 C4317
-Wformat-extra-args -Wformat-extra-args /W3 C4474
-Wmemset-transposed-args -Wmemset-transposed-args C4318
-Wempty-body -Wempty-body /W3 C4390
warning -Wmissing-declarations /W4 C4408
error -Wunicode /W4 C4429
- -Wshadow - -Wshadow /W4 C4456, C4457, C4458, C4459
-Wbitfield-constant-conversion /W4 C4463
-Waddress -Wcomma /W1 C4545, C4546
-Wcomma /W4 C4913
-Wtautological-compare -Wunused-comparison /W1 C4547
-Wunused-value -Wunused-comparison /W1 C4549, C4553
-Wunused-value -Wunused-value /W1 C4548, C4552, C4555
-Wunused-value (-Waddress) -Wunused-value /W1 C4551
-Wparentheses -Wshift-op-parentheses /W3 C4554
-Wmultichar error /W1 C4566
-Winaccessible-base -Winaccessible-base /W1 C4584
- -Wundef - -Wundef /W4 C4668
-Wuninitialized -Wuninitialized /W1,4 C4700
-Wsometimes-uninitialized /W4 C4701, C4703
- -Wunreachable-code - -Wunreachable-code /W1 C4288
- -Wunreachable-code - -Wunreachable-code /W4 C4702
-Wparentheses -Wparentheses /W4 C4706
-Wcomma-subscript -Wdeprecated-comma-subscript /W4 C4709
-Wreturn-type -Wreturn-type /W1 C4715, C4716
-Winfinite-recursion /W1 C4717
-Wdiv-by-zero -Wdivision-by-zero /W3 C4723, C4274
-Wcast-align /W1 C4739
-Wfortify-source /W1 C4789
-Wbool-compare -Wtautological-constant-out-of-range-compare /W1 C4806
-Wswitch-outside-range (-Wswitch-bool) /W1 C4808
-Wvexing-parse /W1 C4930
-Wreinterpret-base-class /W1 C4946
-Wdeprecated -Wdeprecated /W1 C4973, C4974
warning -Wc++17-extensions C4984
-Wdeprecated-declarations -Wdeprecated-declarations /W3 C4996
-Wreorder -Wreorder-ctor C5038
-Wexpansion-to-defined -Wexpansion-to-defined /W1 C5105
-Wabstract-final-class
-Wconversion-null -Wnull-conversion
-Wdangling-else -Wdangling-else