为什么 clang -Wempty-body 没有检测到这种情况?

why clang -Wempty-body doesn't detect this case?

在回答了之后,我停止了理论上的回答,并在我的Windows盒子上安装了clang,在警告诊断部门检查它是否真的比gcc好.

我在 clang 中使用 -Wempty-body 来编译这段代码,这是错误的,因为:

错误代码:

int main(void)
{
   char c=1;
   while (c);
   --c;
   if (c);
}

我尝试用 clang (5.0.0 x64 windows) 编译它:

输出:

S:\c>clang -Wempty-body test.c
test.c:8:10: warning: if statement has empty body [-Wempty-body]
   if (c);
         ^

所以检测到空 ifwhile 不是。

现在我将减量指令包装在 while:

之后的一个块中
int main(void)
{
   char c=1;
   while (c);
   { --c; }
   if (c);
}

现在似乎可以正确检测两者:

test.c:6:10: warning: if statement has empty body [-Wempty-body]
   if (c);
test.c:4:13: warning: while loop has empty body [-Wempty-body]
   while (c);

注意:gcc 无法看到任何 while 错误,因此 clang 在警告检测方面仍然明显优越(另请参阅

这背后的启发是什么?那是一个错误吗?

这是为了避免太多的误报。一般来说,if (expr); 从来没有意义,但 while (expr); 不一定是错误,因为 expr 的副作用可能导致表达式从 true 切换为 false。例如,

void processAllElements() {
  while (tryProcessNextElement());
}

以下是 the source 的解释:

// `for(...);' and `while(...);' are popular idioms, so in order to keep
// noise level low, emit diagnostics only if for/while is followed by a
// CompoundStmt, e.g.:
//    for (int i = 0; i < n; i++);
//    {
//      a(i);
//    }
// or if for/while is followed by a statement with more indentation
// than for/while itself:
//    for (int i = 0; i < n; i++);
//      a(i);