🎺

gccとclangのワーニングの違い

2021/03/28に公開

はじめに

趣味でspresense用のnuttxのビルドをclangでやってみたのですが、
そのときに、gccでは出なかったワーニングが出てきたので調べてみました。
ワーニングなんて、どのコンパイラでも出る内容は同じだと思っていたのですが、
違うのですね、という話。

使用するgccとclangのバージョンは以下

$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir:

ワーニングだらけのコード

サンプルとして以下のようなコードを用意します。

sample.c
#include <stdio.h>

int f(int i){
	int ret;

	if(i<5) goto error;

	if(i);

	if(i <= 2 && i >= 7){
		return 1;
	}

error:
	if(ret) return 1;

	return 0;
}

int main(void){
	int i = f(10);
	printf("%d\n",i);
	return 0;
}

コンパイル

gccでコンパイル

$ gcc -Wall sample.c 
sample.c: In function ‘f’:
sample.c:15:4: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   15 |  if(ret) return 1;
      |    ^

clangでコンパイル

$ clang -Wall sample.c 
sample.c:8:7: warning: if statement has empty body [-Wempty-body]
        if(i);
             ^
sample.c:8:7: note: put the semicolon on a separate line to silence this warning
sample.c:10:12: warning: overlapping comparisons always evaluate to false [-Wtautological-overlap-compare]
        if(i <= 2 && i >= 7){
           ~~~~~~~^~~~~~~~~
sample.c:15:5: warning: variable 'ret' is uninitialized when used here [-Wuninitialized]
        if(ret) return 1;
           ^~~
sample.c:4:9: note: initialize the variable 'ret' to silence this warning
        int ret;
               ^
                = 0
3 warnings generated.

ドキュメント

clangのドキュメントにDiagnostic flags in Clangというところに説明が記載されている。
gccの場合は3.8 Options to Request or Suppress Warningsに書かれている。

まとめ

ワーニングがたくさん出るclangの方が良い、という話ではないです(あたりまえですが)。
コンパイラを変えると色々変わるのが(少し)解ってお勉強になりました。

Discussion