Jean-François Fabre Jean-François Fabre - 3 years ago 124
C Question

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

After answering Xcode- C programming - While loop, I stopped making theoric answers and installed

clang
on my Windows box to check if it's really better than
gcc
in the warning diagnostics department.

I'm using
-Wempty-body
in
clang
to compile this code, which is wrong because:


  • the while instruction ends with a semicolon, possible typo after long hours ending lines with semicolons...: infinite loop

  • same thing for
    if
    statement, making the test useless



wrong code:

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


I tried to compile it with
clang
(5.0.0 x64 windows):

output:

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


So empty
if
is detected while
while
isn't.

Now I'm wrapping the decrement instruction in a block after the
while
:

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


now it seems to detect both properly:

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);


note:
gcc
wasn't able to see either
while
bug, so
clang
is still clearly superior in terms of warning detection (see also why am I not getting an "used uninitialized" warning from gcc in this trivial example?)

What's the heuristics behind this? Is that a bug?

hvd hvd
Answer Source

It's to avoid too many false positives. In general, if (expr); never makes sense, but while (expr); need not be an error, because expr's side effects could cause the expression to switch from true to false. For instance,

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

Here's how the source explains it:

// `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);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download