Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 779
AlphaGoku Avatar asked May 27 '16 11:05

AlphaGoku


People also ask

Can IF statement be empty?

Empty Statement in if … else Statement In the above code snippet, the if the condition has the empty body (or statement) as we have put a semicolon immediately after the if statement. Similar to loops, we can re-write the above code snippet as: int k = -1; if(k < 0)

What does empty if statement mean?

An empty statement does nothing. It's simply allowed and it's equivalent to (and will be translated to): if (condition) { } Which means, if the condition is true, do nothing.

Does an if statement check every condition?

The answer is yes, it will check every if statements. The reason is simple, you are not breaking out of the loop after a condition is evaluated to true.


2 Answers

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
like image 167
Matteo Italia Avatar answered Oct 19 '22 07:10

Matteo Italia


As Matteo's answer indicated, the code is absolutely valid. It's being interpreted this way:

if(condition)     ;  // do nothing  // unrelated block {     // do something } 

It's a bit of a technicality, but conditions with empty bodies do have some very nice uses.

Lint and other such code sanity tools will warn about the unexpected change in indentation, and catch additional errors that may be stylistic though not technically compiler errors.

Or security problems, variable tainting, buffer management, potential maintenance problems like bad casts, etc. There are an awful lot of code problems that don't fall into the category of "compiler errors".

As @jpmc26 mentioned, this approach may be better since you don't have to switch compilers to use it. Though I also personally find value in the ability to run the two independently.

like image 23
davenpcj Avatar answered Oct 19 '22 08:10

davenpcj