我使用了Keil uVision v4.74并启用了选项"所有警告"。
我写了以下故意代码:
if(condition matched)
{
//do something
}
当我重建我的项目时,我得到0个错误,0个警告。
然而,当我意外地写道:
if(condition matched);
{
//do something
}
我也有0个错误,0个警告。
我几乎不可能发现if条件之后的小;
是问题的根源。
为什么编译器没有将其视为警告并通知我?
答案 0 :(得分:52)
这不是错误,因为空语句是有效语句;但是,因为它肯定是可疑的代码,它是编译器警告的完美候选者 - 实际上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
答案 1 :(得分:2)
正如Matteo的回答所示,代码绝对有效。 它被这样解释:
{{1}}
这有点技术性,但空体的条件确实有一些非常好的用途。
Lint和其他此类代码健全工具将警告缩进的意外更改,并捕获可能具有风格的其他错误,尽管不是技术上的编译器错误。
或者安全性问题,可变污点,缓冲区管理,潜在的维护问题,例如糟糕的演员表等。有很多代码问题不属于编译错误的范畴"
正如@jpmc26所提到的,这种方法可能会更好,因为您不必切换编译器来使用它。虽然我个人也发现了独立运行这两者的能力。