为什么编译器没有警告我一个空的if语句?

时间:2016-05-27 11:56:03

标签: c if-statement compiler-warnings keil

我使用了Keil uVision v4.74并启用了选项"所有警告"。

我写了以下故意代码:

if(condition matched)
{
 //do something
}

当我重建我的项目时,我得到0个错误,0个警告。

然而,当我意外地写道:

if(condition matched);
{
 //do something
}

我也有0个错误,0个警告。

我几乎不可能发现if条件之后的小;是问题的根源。

为什么编译器没有将其视为警告并通知我?

2 个答案:

答案 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); {
^

https://godbolt.org/g/RG1o7t

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

答案 1 :(得分:2)

正如Matteo的回答所示,代码绝对有效。 它被这样解释:

{{1}}

这有点技术性,但空体的条件确实有一些非常好的用途。

Lint和其他此类代码健全工具将警告缩进的意外更改,并捕获可能具有风格的其他错误,尽管不是技术上的编译器错误。

或者安全性问题,可变污点,缓冲区管理,潜在的维护问题,例如糟糕的演员表等。有很多代码问题不属于编译错误的范畴"

正如@jpmc26所提到的,这种方法可能会更好,因为您不必切换编译器来使用它。虽然我个人也发现了独立运行这两者的能力。