Edited at

gccで Wall & Wextra を使っても有効にならない警告

More than 3 years have passed since last update.

gccで-Wall -Wextraを付けてもなお有効化されない警告オプションがあるそうなので、ドキュメントを読んでその効能を簡単に調べた。

なお、これらのオプションの中にはfortran、Objective-C用のものもあるようだが、それらについては説明を省く。

検証環境:

gcc (Rev3, Built by MSYS2 project) 5.2.0


(やや特異な環境なのでLinuxなどの一般的な環境とは状況が違うかもしれない)

参考:

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html

https://gcc.gnu.org/onlinedocs/gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html

https://gcc.gnu.org/onlinedocs/gfortran/Error-and-Warning-Options.html


C/C++用オプション


-Wabi

-fabi-version=オプションでABIバージョンを指定したときのみに役に立つオプション。

他バージョンのABIと互換性のない記述に警告を出す。


-Wabi-tag

abi-tag(マングルされた名前に文字列を付与する機能?)の間違った使用に警告を出す。


-Waggregate-return

関数がaggregate(配列や構造体など?)を返す場合に警告を出す。


-Wbad-function-cast

関数呼び出しがマッチしない型にキャストされている場合に警告を出す。

(整数型・浮動小数点数型間の変換に警告を出す?)


-Wc++-compat -Wc++0x-compat -Wc++14-compat

それぞれ、ISO C++、C++0x、C++14と互換のない記述に警告を出す。


-Wcast-align

アラインメントが変わるようなポインタのキャストに警告を出す。

例:char* -> int*のキャスト

(charは1byteだが、intはそれ以上なので間違った位置にアクセスする可能性がある)


-Wcast-qual

type qualifier(const,volatileなど)を外すようなポインタのキャストに警告を出す。


-Wconditionally-supported

不明

(Warn for conditionally-supported (C++11 [intro.defs]) constructs.)


-Wconversion

暗黙型変換のうち、表す値が変わる可能性のあるものに警告を出す。

明示的に変換すれば警告は出ない。

例:unsigned u = -1 //符号付きから符号無しへの変換


-Wctor-dtor-privacy

全てのコンストラクタ・デストラクタがprivateであり、かつfriendpublic static関数も持たないクラス(=使用できないクラス)に対して警告を出す。

また、全てのメンバがprivatefriendも持たないクラスに対しても警告を出す。


-Wdate-time

__TIME__,__DATE__,__TIMESTAMP__マクロを使用している場合に警告を出す。

(これらのマクロを使うと日時によってコンパイル結果が違う可能性があるため)


-Wdelete-non-virtual-dtor

仮想関数を持っているのにデストラクタが仮想関数でないクラスに対して、deleteを使っている場合に警告を出す。


-Wdisabled-optimization

コードが長すぎたり複雑すぎたりして、コンパイラが最適化を実行できない場合に警告を出す。


-Wdouble-promotion

float型が暗黙にdoubleにキャストされている場合に警告を出す。

例:

float area(float radius)

{
return 3.14159 * radius * radius;
}

(浮動小数点数リテラルはdouble型なので、radiusが暗黙にfloat -> double変換されている)


-Weffc++

Scott Meyers の Effective C++ による次の方針に沿わない記述に警告を出す。

・動的確保を利用するクラスにはコピーコンストラクタと代入演算子を定義する。

・コンストラクタ内での代入より、メンバ初期化子を使う。

operator=*thisへの参照を返す。

・オブジェクトを返すべき時に、参照を返そうとしない。

・インクリメント・デクリメントの前置・後置を区別する。

(一般には、前置は参照を返すが、後置はconstコピーを返す)

&&,||,,演算子をオーバーロードしない。


-Wfloat-equal

浮動小数点数を==!=で比較している場合に警告を出す。


-Wformat-nonliteral -Wformat-security -Wformat-signedness

-Wformatが指定されている場合に、printfscanfの書式指定を検証し、それぞれ次の場合に警告を出す。

-Wformat-nonliteral:書式指定の文字列が文字列リテラルでない場合

-Wformat-security:セキュリティ上の問題(書式指定がリテラルでない、書式指定がない、%nの使用)がある場合

-Wformat-signedness:変数とそれに対応する書式指定の、一方がsignedでもう一方がunsignedの場合 (例:'%d'に対して'unsigned'を対応させている)


-Wformat-y2k

-Wformatが指定されている場合に、strftimeの書式指定を検証し、2桁の年号を返す書式指定がされている場合に警告を出す。(Y2K問題への対処)


-Winit-self

-Wuninitializedが指定されている場合に、初期化されていない変数をそれ自身で初期化している場合に警告を出す。

例:int i = i;


-Winline

inline指定されている関数を、コンパイラが(関数が長すぎるなどの理由で)インライン展開しなかった場合に警告を出す。


-Winvalid-pch

コンパイル済みヘッダを発見したが使用できない場合に警告を出す。


-Wjump-misses-init

gotoswitchで変数宣言を通り過ぎる場合に警告を出す。


-Wlogical-op

論理演算子の間違っているかもしれない使用に対して警告を出す。


-Wmissing-declarations

呼び出される前に宣言の無いグローバル関数に対して警告を出す。


-Wmissing-include-dirs

#includeで指定されたディレクトリが見つからない場合に警告を出す。


-Wmissing-prototypes

プロトタイプ宣言の無いグローバル関数に対して警告を出す。


-Wmultichar

複数の文字を含む文字リテラルに対して警告を出す。


-Wnested-externs

不明

(Warn if an extern declaration is encountered within a function.)


-Wnoexcept

不明

(Warn when a noexcept-expression evaluates to false because of a call to a function that does not have a non-throwing exception specification (i.e. throw() or noexcept) but is known by the compiler to never throw an exception.)


-Wnon-virtual-dtor

クラスが、仮想関数と、(そのクラスまたは基底クラスに)アクセス可能な非仮想デストラクタを持っているときに警告を出す。

このオプションは-Weffc++が指定されると自動的に有効となる。


-Wold-style-cast

C++コード内でC形式のキャストを使用した場合に警告を出す。

例: (int)foo ではなく static_cast<int>(foo) を使う


-Wold-style-definition

K&Rスタイルの関数定義に対して警告を出す。


-Woverlength-strings

Cにおいて、規格で定められた文字列長の「最小限の最大長」を超える文字列に対して警告を出す。

この長さは、C90では509文字、C99では4095文字である。なお、C++では規定がないので検査されない。

このオプションは、-Wpedanticが指定されると自動的に有効になる。


-Woverloaded-virtual

派生クラスの関数との名前被りによって、基底クラスのvirtual関数が使えなくなる場合に警告を出す。

例:

struct A {

virtual void f();
};

struct B: public A {
void f(int);
};

このようなクラス定義の下では、次のコードはコンパイルできない。

B* b;

b->f();


-Wpacked

構造体にpacked attributeが指定されているが、実際には効果がない場合に警告を出す。


-Wpadded

構造体にパディングが挿入された場合に警告を出す。


-Wpedantic

gccの拡張構文を無効に対して警告を出す。


-Wpointer-arith

関数型、void型に対するsizeofの適用に対して警告を出す。

(これらの型に対するsizeofの適用はISO C/C++ではundefinedであるが、gccでは1を返す)

例:

double f(){}

sizeof(void) // エラー
sizeof(char(int,long)) // エラー
sizeof(f) // エラー


-Wredundant-decls

同じスコープで2回以上宣言されているものがある場合に警告を出す。


-Wreorder

コンストラクタのメンバ初期化子と、メンバ変数の宣言の順番が異なる場合に警告を出す。


-Wshadow

名前被りに対して警告を出す。


-Wsign-promo

オーバーロードによってunsigned ~enumが、signed ~に型変換される場合に警告を出す。


-Wstack-protector

-fstack-protectorが指定されている場合に、スタック保護がなされなかった関数が存在する場合に警告を出す。


-Wstrict-null-sentinel

キャストされていないNULLが番兵として使用されている場合に警告を出す。

gccにおいてはこの手法を用いたコードで問題は生じないが、他の処理系でうまく動く保証はない。


-Wstrict-prototypes

引数の型が指定されていない(K&Rスタイルの)プロトタイプに対して警告を出す。


-Wsuggest-attribute=[const|format|noreturn|pure]

指定したattributeを付けたほうが良いかもしれない部分に対して警告を出す。


-Wsuggest-final-methods -Wsuggest-final-types

finalを付けたほうがいいかもしれない部分に対して警告を出す。


-Wsuggest-override

overrideを付けたほうがいいかもしれない部分に対して警告を出す。


-Wswitch-default

switch文がdefaultラベルの文を持たない場合に警告を出す。


-Wswitch-enum

switch文の対象になる値がenumで、ラベルがenumのすべての値には対応していない場合に警告を出す。


-Wsystem-headers

システムヘッダ内の問題に対しても警告を出すようにする。


-Wtraditional -Wtraditional-conversion

"伝統的な" C (ISO策定以前のC) と ISO C で動作の異なる部分に対して警告を出す。


-Wtrampolines

不明

(Warn about trampolines generated for pointers to nested functions. A trampoline is a small piece of data or code that is created at run time on the stack when the address of a nested function is taken, and is used to call the nested function indirectly. For some targets, it is made up of data only and thus requires no special treatment. But, for most targets, it is made up of code and thus requires the stack to be made executable in order for the program to work properly.)


-Wundef

定義されていない識別子が#ifディレクティブで評価されている場合に警告を出す。


-Wunsafe-loop-optimizations

ループカウンタがオーバーフローする可能性があって、ループを最適化できない場合に警告を出す。


-Wunsuffixed-float-constants

接尾辞のついていない浮動小数点数リテラルに対して警告を出す。


-Wuseless-cast

変数を、その変数自身の型にキャストしている(無意味である)場合に警告を出す。


-Wvariadic-macros

variadic macro(可変引数マクロ)が使用されている場合に警告を出す。


-Wvector-operation-performance

アーキテクチャがSIMDをサポートしていないために、ベクトル演算を使用できない場合に警告を出す。


-Wwrite-strings

文字列リテラル(const char*)をchar*へ型変換する場合に警告を出す。


-Wzero-as-null-pointer-constant

整数リテラル'0'がヌルポインタを示す定数として使われている場合に警告を出力する。


プリプロセッサ用オプション


-Wunused-macros

使用されていないマクロに対して警告を出す。


Fortran用オプション

-Waliasing

-Wampersand

-Warray-temporaries

-Wc-binding-type

-Wcharacter-truncation

-Wcompare-reals

-Wconversion-extra

-Wfunction-elimination

-Wimplicit-interface

-Wimplicit-procedure

-Wintrinsic-shadow

-Wintrinsics-std

-Wreal-q-constant

-Wrealloc-lhs

-Wrealloc-lhs-all

-Wsurprising

-Wtabs

-Wtarget-lifetime

-Wunused-dummy-argument

-Wuse-without-only

-Wzerotrip


Objective-C用オプション

-Wassign-intercept

-Wselector

-Wstrict-selector-match

-Wundeclared-selector


GCCのドキュメントに記述なし

-Wchkp(Pointer Bounds Checker関係?)

-Wsynth(C++関係?)