2012年01月24日

GCCでunsignedの変数を0と比較したときにwarningを出すオプション

昨日、自分で修正したプログラムが意図した通りに動作しなくて少し悩んだのですが、それはunsignedの型の変数に負数を代入して、0と比較している部分が正しく動かなかったためでした。unsignedの型の変数は0より小さくなることはありません。

でも、こんなケースではgccはwarningを出して教えてくれたはず。実はオプションの指定が必要でした。



サンプルプログラム

以下のプログラムではxがどんな値でも5行めのif文が真になることは無いので常にret = 2になります。

$ cat -n b.c
     1	int
     2	b(unsigned int x)
     3	{
     4	    int ret;
     5	    if (x < 0) {
     6	        ret = 1;
     7	    } else {
     8	        ret = 2;
     9	    }
    10	    return ret;
    11	}
    12	

試したのはUbuntu 10.04でapt-getでインストールしたgccです。

$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 

まず普通にコンパイル。

$ gcc -c b.c
$

何もwarningがでません。次に -Wall をつけてみます。

$ gcc -Wall -c b.c
$

おや?これでもでません。

$ gcc -W -c b.c
b.c: In function ‘b’:
b.c:5: warning: comparison of unsigned expression < 0 is always false
$

やっとでました。

オプション -Wall で全てのwarningが有効になると勘違いしていました。-Wextra とすると-Wallよりもたくさんのwarningが出ます。-W は -Wextraの古い書き方です。

つまり、warningの出る種類の多さに関しては

-Wextra = -W > -Wall

参考までに、warningを止めるには -w (小文字のw)

今回のものだけ個別に有効にするには以下のようにします。

$ gcc -Wtype-limits -c b.c
b.c: In function ‘b’:
b.c:5: warning: comparison of unsigned expression < 0 is always false
$

gccのマニュアル

gccのマニュアルから関連するところを抜粋しておきます。

-Wall
    This enables all the warnings about constructions that some users consider questionable, 
    and that are easy to avoid (or modify to prevent the warning), even in conjunction with
    macros.   This also enables some language-specific warnings described in C++ Dialect 
    Options and Objective-C and Objective-C++ Dialect Options.

    -Wall turns on the following warning flags:

              -Waddress   
              -Warray-bounds (only with -O2)  
              -Wc++0x-compat  
              -Wchar-subscripts  
              -Wimplicit-int  
              -Wimplicit-function-declaration  
              -Wcomment  
              -Wformat   
              -Wmain (only for C/ObjC and unless -ffreestanding)  
              -Wmissing-braces  
              -Wnonnull  
              -Wparentheses  
              -Wpointer-sign  
              -Wreorder   
              -Wreturn-type  
              -Wsequence-point  
              -Wsign-compare (only in C++)  
              -Wstrict-aliasing  
              -Wstrict-overflow=1  
              -Wswitch  
              -Wtrigraphs  
              -Wuninitialized  
              -Wunknown-pragmas  
              -Wunused-function  
              -Wunused-label     
              -Wunused-value     
              -Wunused-variable  
              -Wvolatile-register-var 
              
         

    Note that some warning flags are not implied by -Wall. Some of them warn about constructions 
    that users generally do not consider questionable, but which occasionally you might wish
    to check for; others warn about constructions that are necessary or hard to avoid in some cases, 
    and there is no simple way to modify the code to suppress the warning. Some of them are 
    enabled by -Wextra but many of them must be enabled individually.

-Wextra
    This enables some extra warning flags that are not enabled by -Wall. (This option used to be
    called -W. The older name is still supported, but the newer name is more descriptive.)

              -Wclobbered  
              -Wempty-body  
              -Wignored-qualifiers 
              -Wmissing-field-initializers  
              -Wmissing-parameter-type (C only)  
              -Wold-style-declaration (C only)  
              -Woverride-init  
              -Wsign-compare  
              -Wtype-limits  
              -Wuninitialized  
              -Wunused-parameter (only with -Wunused or -Wall)  
              
         

    The option -Wextra also prints warning messages for the following cases:

        * A pointer is compared against integer zero with `<', `<=', `>', or `>='.
        * (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
        * (C++ only) Ambiguous virtual bases.
        * (C++ only) Subscripting an array which has been declared `register'.
        * (C++ only) Taking the address of a variable which has been declared `register'.
        * (C++ only) A base class is not initialized in a derived class' copy constructor. 



トラックバックURL

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード