🎺
gccとclangのワーニングの違い
はじめに
趣味で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