为什么编译器没有警告我空的 if 语句?
Why didn't the compiler warn me about an empty if-statement?
我正在使用 Keil µVision v4.74 并启用了“所有警告”选项。
我写了以下有意代码:
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 and Visual C++也这样做。
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
标志时):
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
;
- 叮当
-Wempty-body
;也包含在 -Wextra
中;
- Visual C++C4390,包含在
/W3
中
静态分析工具:
- cppcheck
--enable=warning --inconclusive
;包含在 --enable=all --inconclusive
如所示,代码绝对有效。
它被这样解释:
if(condition)
; // do nothing
// unrelated block
{
// do something
}
这有点技术性,但空体条件确实有一些非常好的用途。
Lint 和其他此类代码完整性工具将警告缩进的意外更改,并捕获可能是风格上的但不是技术上的编译器错误的其他错误。
或安全问题、变量污染、缓冲区管理、潜在的维护问题(如错误转换)等。有大量代码问题不属于“编译器错误”类别。
与 一样,这种方法可能更好,因为您不必切换编译器即可使用它。尽管我个人也发现 运行 两者独立的能力的价值。
我正在使用 Keil µVision v4.74 并启用了“所有警告”选项。
我写了以下有意代码:
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 and Visual C++也这样做。
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
标志时):
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
; - 叮当
-Wempty-body
;也包含在-Wextra
中; - Visual C++C4390,包含在
/W3
中
静态分析工具:
- cppcheck
--enable=warning --inconclusive
;包含在--enable=all --inconclusive
如
if(condition)
; // do nothing
// unrelated block
{
// do something
}
这有点技术性,但空体条件确实有一些非常好的用途。
Lint 和其他此类代码完整性工具将警告缩进的意外更改,并捕获可能是风格上的但不是技术上的编译器错误的其他错误。
或安全问题、变量污染、缓冲区管理、潜在的维护问题(如错误转换)等。有大量代码问题不属于“编译器错误”类别。
与