2

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?

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219

1 Answers1

4

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);
  • exactly what I wrote in may comment. while (); is in too common use to warn every time. – 0___________ Sep 30 '17 at 16:30
  • @PeterJ_01 Not exactly the same as what you wrote. In fact, I disagree with what you wrote for the same reason that Antti Haapala did. –  Sep 30 '17 at 16:37
  • C means any statement - by coincidence OP used this letter for the variable name. Very narrow tunnel vision :) – 0___________ Sep 30 '17 at 16:59