Search code examples
cif-statementcompiler-warningskeil

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


I'm using Keil µVision 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?


Solution

  • 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 Visual C++ 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):

    cppcheck --enable=all --inconclusive emptyif.c
    

    Output:

    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