Semicolon at end of 'if' statement

JavaIf Statement

Java Problem Overview


Today, after half an hour of searching for a bug, I discovered that it is possible to put a semicolon after an if statement instead of code, like this:

if(a == b);
// Do stuff

Which basically means that the stuff will be done whether a equals b or not, and the if statement has no point whatsoever. Why doesn't Java give me an error? Is there any situation in which this would be useful?

Java Solutions


Solution 1 - Java

Why does it happen?

Java Language Specification says that: >The Empty Statement > > An empty statement does nothing. > > EmptyStatement: > ; > Execution of an empty statement always completes normally

It essentially means that you want to execute empty statement if a==b

if(a == b);

What should you do:

There are two main solutions to this problem:

  1. You can avoid problems with empty statement by using code formatter and surrounding stuff inside if with { and }. By doing this Your empty statement will be much more readable.

    if(a == b){
      ;
    }
    
  2. You can also check tools used for static code analysis such as:

    They can instantly highlight problems such as this one.

I would recommend to combine both solutions.

Solution 2 - Java

> Is there any situation in which this would be useful?

Useful? As in "makes your code cleaner, clearer, faster, more maintainable"? Not at all. This is most likely poor, confusing code.

But it's not necessarily benign. Such a statement can perform actions and/or alter state due to methods which cause side effects, and optionally evaluate those methods due to short-circuiting of operators.

if( a() && b() );

Here, a() or b() may do something, and b() will only execute if a() is true.

As to why, I think the answer is simply that it would be worse to deviate from defined, expected behavior (e.g. statements like while(reader.read());) than the alternative of developers writing bad code.

Writing bad code is always possible. And just to reiterate, this would be bad code in almost any case.

Solution 3 - Java

A possible use case:

if (a==b);
else {
  // Do something
}

Not good, but possible.

Still, I do think that the Java specification should disallow an empty if.

Solution 4 - Java

If you're using Eclipse, you can make it warn you about those statements:

Java->Compiler->Errors/Warnings

Solution 5 - Java

If you use an if statement, the first statement after the if will be executed if the condition is true. If you have a block after the if (with curly braces), it counts for that whole block. If there is no block it counts for only one statement. A single semicolon is an empty statement. You could also write the code from you example like this:

if(a==b) {
    ;
}

Solution 6 - Java

It is an old leftover from the days when there was more syntactic sugar to differentiate expressions from statements.

Basically, the comma was used as the list item separator, so the semicolon was used as the "list of statements" separator. The downside is in the handling of null items in lists, and null statements in blocks.

In a list of items, Java uses the explicit keyword null, but a "null statement" is just an empty line. Allowing the existence of an empty line is a holdover from tradition inherited from C.

Why do it? Especially with an if statement when you know that no statements are being executed: Because some if statements have side effects:

 int c;
 if ((c = in.read()) != -1);

Yes, it is not the best example, but basically it says read a byte from the stream and do nothing. Might be useful in some corner cases, but even if this example isn't the best, it illustrates the intent. We want to feel the side-effects of the expression without accidentally executing any statements.

Solution 7 - Java

I can't think of an occasion where it is useful. It can be useful for loops like

 while(do something);

or

 for(init; do something; something else);

If you use your code formatting in your IDE regularly these sort of bugs become obvious. Some IDEs highlight this as a probable bug as well.

Solution 8 - Java

I'd agree with you there's no useful purpose to this for a human. I suspect it's there because it simplifies the language definition; it means that the thing that comes after an if is e same as the thing that comes after a while, for instance.

Solution 9 - Java

Why? It's because its easier for compiler writers. You don't have to make a special case to check for semicolons after if(cond) and has an added usage of allowing

if (cond && maybeFunc())
    ;// Code here I want to ignore

Even though it's actually a terrible idea to allow this. It's just easier to allow and then to add a case to check this.

Solution 10 - Java

Java allows an empty block any place a statement block is allowed. I am sure making this a general rule for all blocks simplifies the compiler.

I agree that this is primarily the cause of bugs that are spectacularly hard to find. I always use braces around blocks, even when there is a single statement, but Java allows you to make a block with braces at any point, so using braces can not save you from this fate. For example, I once wasted 4 hours trying find something like this:

while (condition);
{
    statement;
    statement;
}

The semicolon at the end of the first line was a typo, accidentally making the statement block for the while loop empty. Because the syntax is valid the program compiled and ran fine, just not the way I wanted it to. It was really hard to find.

I can think of one situation where it is very nice that you are allowed to have empty blocks, and this is something like this:

if (condition1) {
    do_action_1();
}
else if (condition2) {
    //nothing really to do in this case
}
else if (condition3) {
    do_action2();
}
else {
    do_action3();
}

In the above example, you want to be able to separate out various conditions. Remember, those conditions might be overlapping, so it is not always possible to rearrange the order. If one of the conditions really does not need anything done, then it is nice that Java allows you to have an empty block. Otherwise, the language would need some form of a "noop" method to use when you really do not want anything done.

I personally would prefer the explicit "noop" statement -- but that is not how Java is defined.

Solution 11 - Java

Just a FYI about the usability and what difference it makes or can make if there is a statement like that

Consider a piece of code like the following.

int a = 10;
if ((a = 50) == 50);

System.out.println("Value of a = " + a);

Clearly in this case, the if statement does change the output. So a statement like that can make a difference.

This is a situation where this could be useful or better to say have an impact on program.

Solution 12 - Java

if(a==b)
    println("a equals b");

You can use an IF statement without {} if there is only a single line to be executed, so by using if(a==b); you are saying if they equal, execute and empty statement... So it will do nothing, and then return to your normal loop, outside of the IF block.

Solution 13 - Java

A few definitions from the jls explain this (chapter 14):

Blocks are Statements

As stated here, a Block is a StatementWithoutTrailingSubstatement, which in turn is a StatementNoShortIf, which is a Statement. Thus where ever any of these is required, we can insert a Block.

The if-clause

Though this is as well the case for for and while-loops, I'll use if-statements. These rules are pretty much the same. The syntactical description of if-statements can be found here.

IfThenStatement:
    if ( Expression ) Statement

IfThenElseStatement:
    if ( Expression ) StatementNoShortIf else Statement

IfThenElseStatementNoShortIf:
    if ( Expression ) StatementNoShortIf else StatementNoShortIf

So we can use our block here.

But why does it work with ; ?

; is defined as the EmptyStatement (link), which is as well a StatementNoShortIf. So in conditional pieces of code, like if-statement and loops, we can replace a Block with a EmptyStatement, if a StatementNoShortIf or Statement is required.

Thus if(Expression)EmptyStatement works.

Why doesn't this give an error?

Pretty simple: java gives an error if it finds invalid syntax. But if(Expression)EmptyStatement is perfectly valid syntax. Instead javac gives a warning if launched with the proper parameters. The full list of warnings that can be dis-/enabled lists the warning-name empty for this purpose. So compilation with -Xlint:all or -Xlint:empty will generate a warning about this.

Your IDE should have an option to enable this kind of warning as well. For eclipse, see @nullptr's answer. In IntelliJ, you can press Ctrl + Shift + A, enter empty body into the search field and enable the warning (marked in the image)

IntelliJ enable empty-body warning

What is this even used for?

To be honest, there's not much use in it from a minimalistic point of view. There's usually a way to get things done without a "do nothing" command. It's rather a question of personal preferences, whether you rather use

if( a() && b() );

or

if( a() ) b();

and same would apply to other cases, in which the EmptyStatement is used. An important point to consider on this topic is readability of code. There are occasions, where code becomes more readable by using the no-op. On the other hand there are cases, where code becomes quite a lot harder to comprehend with using the EmptyStatement - the above example would count to the later IMO.

Solution 14 - Java

I can think of a scenario where an empty statement is required (not for if condition but for while loop).

When a program just want an explicit confirmation from the user to proceed. This may be required when the work after the user confirmation depends on some other things and user want to take control of when to proceed.

	System.out.println("Enter Y to proceed. Waiting...");
	System.out.println("");
	
	while(!(new Scanner(System.in).next().equalsIgnoreCase("Y")));
	
	System.out.println("Proceeding...");
    // do the work here

Solution 15 - Java

look this:

int a,b,c = 0;
if(a == b){
   c =1;
} 
System.out.print(c);//1

so, you can write like this:

if (a == b)c=1;

but,if this code is this:

int a,b,c=0;
if (a != b){
}
if (a == b ){
  c =1;
}

you can write like this:

if(a != b);
if(a == b )c=1;

so,you will know if(a != b); do noting

Solution 16 - Java

The semi-colon in the if indicates the termination of the if condition as in java ; is treated as the end of a statement, so the statement after if gets executed.

Solution 17 - Java

Semicolon at the end of,
if(a==b); simply finish the statement in single line which means ignore the result of condition and continue the execution from the next line
This code is useful, on the other hand sometime introduce bug in program, for example,

case 1.

a = 5;
b = 3;
if(a == b);
prinf("a and b are equal");

case 2.

a = 5;
b = 5;
if(a == b);
prinf("a and b are equal");
would print the same output on the screen...

Solution 18 - Java

While working on a programming assignment for class where I am working with a N by N grid of doodads and comparing characteristics of a random doodad to those above, below, left, and right, I found a nice use of this to prevent nested statements and potential boundary exceptions. My goal was to minimize code and keep from nesting if-statements.

if (row == 0); 
else (method (grid[row][col], grid[row-1][col]));
if (row == N-1);
else (method (grid[row][col], grid[row+1][col]));
if (col == 0);
else (method (grid[row][col], grid[row][col-1]));
if (col == N-1);<br>
else (method (grid[row][col], grid[row][col+1]));

where method(Doodad a, Doodad b) does some operation between a and b.

Alternatively, you could use exception handling to avoid this syntax, but it works and works well for my application.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionErik BergstenView Question on Stackoverflow
Solution 1 - JavaMarcin SzymczakView Answer on Stackoverflow
Solution 2 - JavaTim M.View Answer on Stackoverflow
Solution 3 - JavagefeiView Answer on Stackoverflow
Solution 4 - JavanullptrView Answer on Stackoverflow
Solution 5 - JavaAndré StannekView Answer on Stackoverflow
Solution 6 - JavaEdwin BuckView Answer on Stackoverflow
Solution 7 - JavaPeter LawreyView Answer on Stackoverflow
Solution 8 - JavayshavitView Answer on Stackoverflow
Solution 9 - Javauser34537View Answer on Stackoverflow
Solution 10 - JavaAgileProView Answer on Stackoverflow
Solution 11 - JavaMukul GoelView Answer on Stackoverflow
Solution 12 - JavaMatt ClarkView Answer on Stackoverflow
Solution 13 - JavaPaulView Answer on Stackoverflow
Solution 14 - JavaParvezView Answer on Stackoverflow
Solution 15 - JavaDMWView Answer on Stackoverflow
Solution 16 - JavaBishal JaiswalView Answer on Stackoverflow
Solution 17 - JavaNarayan BhandariView Answer on Stackoverflow
Solution 18 - JavaGeorge CView Answer on Stackoverflow