为什么编译器没有警告我一个空的if语句?
我正在使用Keil uVision v4.74并启用了“All Warnings”选项。
我写了以下故意代码:
if(condition matched) { //do something }
当我重建我的项目时,我得到0个错误,0个警告。
但是,当我不小心写道:
if(condition matched); { //do something }
我也有0个错误,0个警告。
我几乎不可能发现那么小;
if条件之后是问题的根源。
为什么编译器不将它视为警告并通知我?
这不是错误,因为空语句是有效语句; 然而,因为它肯定是可疑的代码,它是编译器警告的完美候选者 – 实际上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.
附录 – 各种编译器的相关警告(随时更新)
总结一下,相关的警告选项是:
- gcc
-Wempty-body
; 包含在-Wextra
; - gcc > = 6.0,同样
-Wmisleading-indentation
可以提供帮助; 包含在-Wall
; - clang
-Wempty-body
; 包含在-Wextra
; - Visual C ++ C4390 ,包含在
/W3
静态分析工具:
- cppcheck
--enable=warning --inconclusive
; 包含在--enable=all --inconclusive
正如Matteo的回答所示,代码绝对有效。 它被解释为这样:
if(condition) ; // do nothing // unrelated block { // do something }
这有点技术性,但空体的条件确实有一些非常好的用途。
Lint和其他此类代码健全工具将警告缩进的意外更改,并捕获可能是风格的其他错误,尽管不是技术上的编译器错误。
或者安全问题,可变污点,缓冲区管理,潜在的维护问题,例如糟糕的演员表等。有很多代码问题不属于“编译器错误”类别。
正如@ jpmc26所提到的,这种方法可能更好,因为您不必切换编译器来使用它。 虽然我个人也发现了独立运行这两者的能力。