Keil uVision v4.74を使用していますが、[すべての警告]オプションを有効にしています。
私は次の意図的コードを書きました:
if(condition matched)
{
//do something
}
プロジェクトを再構築したときに、エラー0、警告0を受け取りました。
しかし、私が偶然を書いたとき:
if(condition matched);
{
//do something
}
エラー0、警告0も受け取りました。
私は、小さな;
if条件に続くものが問題の根本でした。
なぜコンパイラは警告としてそれを扱い、私に知らせなかったのですか?
空のステートメントisは有効なステートメントであるため、エラーではありません。ただし、それは確かに疑わしいコードであるため、コンパイラ警告の完璧な候補です。実際、gcc -Wall -Wextra
はこれについて警告します。
int foo(int x) {
if(x); {
return 42;
}
return 64;
}
/tmp/gcc-Explorer-compiler116427-37-l1vpg4/example.cpp: In function 'int foo(int)':
2 : warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
if(x); {
^
clang
とVC++も同様です。
gcc 6はさらに賢く(多分多すぎるかもしれません)、インデントさえも何かが間違っているというヒントとして受け取ります。
/tmp/gcc-Explorer-compiler116427-76-1sfy0y/example.cpp: In function 'int foo(int)':
2 : warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
if(x); {
^
2 : warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if(x); {
^~
2 : note: ...this statement, but the latter is misleadingly indented as if it is guarded by the 'if'
if(x); {
^
そのため、警告が十分に上げられていないか、コンパイラが十分に賢くありません。
より有用なコンパイラに切り替えることができない場合は、静的分析ツールの使用を検討してください。たとえば、この場合、cppcheck
はエラーを見つけます(--enable=all --inconclusive
フラグが指定されている場合)。
[mitalia@mitalia ~/scratch]$ cppcheck --enable=all --inconclusive emptyif.c
Checking emptyif.c...
[emptyif.c:2]: (warning, inconclusive) Suspicious use of ; at the end of 'if' statement.
[emptyif.c:1]: (style) The function 'foo' is never used.
要約すると、関連する警告オプションは次のとおりです。
-Wempty-body
; -Wextra
;に含まれています。-Wmisleading-indentation
も役立ちます。 -Wall
;に含まれています。-Wempty-body
; -Wextra
にも含まれています。/W3
に含まれる静的解析ツール:
--enable=warning --inconclusive
; --enable=all --inconclusive
に含まれていますMatteoの答えが示したように、コードは完全に有効です。このように解釈されています:
if(condition)
; // do nothing
// unrelated block
{
// do something
}
それは少し専門的ですが、空のボディを持つ条件にはいくつかの非常に素晴らしい使用があります。
Lintおよび他のそのようなコード健全性ツールは、インデントの予期しない変更について警告し、技術的にはコンパイラエラーではありませんが、スタイル上の追加エラーをキャッチします。
または、セキュリティの問題、変数の汚染、バッファ管理、不正なキャストなどの潜在的なメンテナンスの問題など。「コンパイラエラー」のカテゴリに分類されないコードの問題が非常に多くあります。
@ jpmc26が述べたように、このアプローチは、使用するためにコンパイラを切り替える必要がないため、より良いかもしれません。個人的には、2つを独立して実行できることにも価値があります。