Why didn't the compiler warn me about an empty if-statement?

AlphaGoku picture AlphaGoku · May 27, 2016 · Viewed 18.8k times · Source

I'm using Keil uVision v4.74 and have enabled the option "All Warnings".

I wrote the following intentional code:

if(condition matched)
{
 //do something
}

When I rebuilt my project, I got 0 errors, 0 warnings.

However, when I accidentally wrote:

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

I also got 0 errors, 0 warnings.

It was next to impossible for me to find out that a small ; following the if condition was the root of the problem.

Why didn't the compiler treat it as a warning and inform me?

Answer

Matteo Italia picture Matteo Italia · May 27, 2016

It's not an error because an empty statement is a valid statement; however, since it's certainly suspicious code it's the perfect candidate for a compiler warning - and in fact gcc -Wall -Wextra does warn about this:

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

both clang and VC++ do it too.

gcc 6 is even smarter (well, maybe too much), and takes even the indentation as a hint that something is wrong:

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

So, either you don't have the warnings cranked up enough, or your compiler isn't smart enough.

If you don't have the possibility to switch to a more helpful compiler, consider using static analysis tools; for example, in this case cppcheck spots the error (when given the --enable=all --inconclusive flags):

[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.

Addendum - relevant warnings for various compilers (feel free to update)

to recap, the relevant warning options are:

  • gcc -Wempty-body; included in -Wextra;
  • gcc>=6.0, also -Wmisleading-indentation can help; included in -Wall;
  • clang -Wempty-body; included in -Wextra too;
  • Visual C++ C4390, included in /W3

Static analysis tools:

  • cppcheck --enable=warning --inconclusive; included in --enable=all --inconclusive