26

By "empty if-statement", I mean something like this (note the semicolon):

if (condition);

I'm having trouble thinking of an application for this. With a while loop you can do this:

while (callUntilReturnsFalse());

But there's no such application for an if-statement. What's more, the Java compiler doesn't issue an error or a warning when confronted with such a statement. This can lead to large and silent problems, especially with a long and convoluted statement:

if ((functionA() && functionB(getFoo()) ||
    checkForComplexCondition(arg1, arg2, getBar(getFoo())));
{
    doStuff();
}

My question is: why is this allowed in Java? And, more importantly, can I enable an option to cause a warning when this happens?

(This question was asked before with regards to C#, which does issue a warning, but I was hoping to find a way to cause a warning with Java.)

Community
  • 1
  • 1
nullptr
  • 2,244
  • 1
  • 15
  • 22
  • 1
    @FlorisVelleman What do you mean? Perhaps I should have clarified that I mean statements with no body at all – nullptr May 07 '13 at 21:33
  • There is an option to make the formatting put standalone `;`s on there own line, which would make it easier to catch. I'm not sure of a way to get a warning though. (I assume we are talking about eclipse) – Cemafor May 07 '13 at 21:37
  • See [this question](http://stackoverflow.com/questions/14112515/semicolon-at-end-of-if-statement) for a fairly comprehensive treatment of the subject. At the end of the day, it is a valid (if useless) language construct. You will have better luck finding it via code formatting than trying to get the compiler to notify you. – George Cummins May 07 '13 at 21:43
  • It's not 'useless'. It calls the function. – user207421 Jun 26 '13 at 22:51
  • Notably, if the next statement is an `else` statement, it will only run if `condition` is false. Of course, that whole construct could be written more easily with a `!condition`. It might be useful for the compiler to not give an error if you didn't implement the "`condition` is true" case yet, but still wanted to compile and run the code. – Vaelus Jun 17 '15 at 13:19
  • I use to have this error like 2 times in a year but it always cost me hours of finding it. The ; at the end of a line just looks too familiar (thus right) and I usually only find it when I make 100% sure that exactly that condition was behaving wrongly. I can see it not being an error but it should be highlighted as a warning directly in the ide. – FrankKrumnow Sep 08 '21 at 08:25

9 Answers9

16

why is this allowed in Java?

See Java Language Specification (14.6. The Empty Statement):

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.

If you're using eclipse, you can look here, you might find something useful (I'm not sure there exists such an option for semicolon terminator):

WindowPreferencesJavaCompilerError/Warnings

enter image description here


EDIT

As @nullptr pointed out in his answer, there exist an IDE warning for this, you need to set warning on Empty statement.

Maroun
  • 94,125
  • 30
  • 188
  • 241
14

I don't think this is truly relevant to the intent of the question but I think it should be stated as it is relevant to the essence of the question.

There is an effect of an:

if(variable);

if the variable is volatile. It''s effect is to cause a memory barrier to be honoured between the current thread and any other threads accessing the variable.

public volatile variable;
....
if(variable);

See here for a more detailed discussion.

I cannot imagine any real value to putting this kind of statement in your code but I felt it important to note that there is a real effect to this statement in this very specific situation.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
7

There's one construct that I use fairly frequently which the "null statement" makes clearer and easier to understand. Here's an example:

for (int i=0;  i < argc;  i++)
{
   if (argv[i]=="left")
      hpos++;
   else if (argv[i]=="right")
      hpos--;
   else if (argv[i]=="up")
      ;
   else if (arv[i]=="down")
      ;
   else fprintf(stderr, "Unknown option \"%s\\n".", argv[i]);
}

In this case, I still want to check for the existence of certain options, while only executing code for some of them. In this case, using the null statement, as above, makes the function and structure of the code more readable and comprehensible to the next guy who has to come along and maintain it.

There are certainly ways to restructure this code to not require the null statement. But I don't believe that its intention will be as clear as in the code snippet.

Curt
  • 5,518
  • 1
  • 21
  • 35
  • Didnt consider that... There are better ways sure, but at least i now know why my IDE said that this is sometimes intentional while i was writing an if block (hadnt populated it yet and i read the tooltip on the warning) – Nicholas Terry Jan 22 '16 at 16:16
  • I also found that in some cases I need the empty statement on purpose for logic clarity. However I do not want to turn off the empty statement warning. Is there a way to indicate this line is on purpose so that Eclipse does not give warning? – fchen Feb 07 '22 at 14:21
3

I found a warning for this in Eclipse as Empty statement:

example

Thanks to Maroun Maroun for putting me on the right track.

nullptr
  • 2,244
  • 1
  • 15
  • 22
2

I don't see so much danger in the possibility of an if with an empty statement. The rationale behind it resides in the grammar of the Java language, which allows the empty statement ;:

Block: 
    { BlockStatements }

BlockStatements: 
    { BlockStatement }

BlockStatement:
    LocalVariableDeclarationStatement
    ClassOrInterfaceDeclaration
    [Identifier :] Statement

LocalVariableDeclarationStatement:
    { VariableModifier }  Type VariableDeclarators ;

Statement:
    Block
    ;
    Identifier : Statement
    StatementExpression ;
    if ParExpression Statement [else Statement] 
    assert Expression [: Expression] ;
    switch ParExpression { SwitchBlockStatementGroups } 
    while ParExpression Statement
    do Statement while ParExpression ;
    for ( ForControl ) Statement
    break [Identifier] ;
    continue [Identifier] ;
    return [Expression] ;
    throw Expression ;
    synchronized ParExpression Block
    try Block (Catches | [Catches] Finally)
    try ResourceSpecification Block [Catches] [Finally]

Mind that this is true for almost all imperative languages.

I mean it can be dangerous and difficult to find as every other empty body in case you forgot any implementation, certainly nothing I would lose the sleep for. In a long and convoluted statement you could get problems because of a ( ) closing the wrong pair of expressions or even for thinking your condition wrong (especially with many && and ||).

Jack
  • 131,802
  • 30
  • 241
  • 343
1

I'm mostly a C# developer, although I have a little Java background. But I think my answer applies to both. I suspect it's not an intentional feature, but more of an emergent feature. The grammar of the language goes (roughly)

if (*condition*)
    *statement*

Unfortunately the below are both valid statements (I checked, you can drop as many into C# as you like and the compiler doesn't complain):

;

{
}

Therefore the construct that you highlighted is allowed.

David Cummins
  • 972
  • 6
  • 15
1

The condition could be a function call with side effects. It wouldn't be correct to treat it as an error or warning.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

In the statement

if  (eval) { //pseudo-code
}

Sometimes data is actually changed in evaluation of (eval). For example, in

while (someIterator.next()) {
}

Calling next() actually changes the state of the someIterator object.

And of course there is the classic example that usually happens from a typo (and is not recommended)

int x;  
if (x = getNumberOfWidgets() > 5) {
}

Conventional wisdom advises against coding this way, as it is harder to tell what is going on. However, the statements are legal and so that is one reason why such an 'if' statement is allowed.

user1445967
  • 1,520
  • 4
  • 14
  • 30
  • But how is saying `if (eval);` different from just saying `eval`? – nullptr May 07 '13 at 21:45
  • In your if(eval); example, it is not different. However that does not make it an illegal statement. HOWEVER in the example `if (evalsToFalse && evalsToTrue);` , the second evaluation will not be performed due to the lazy evaluation of the && operator. So there can be some differences in a case like this. But there is often more than one way to do the same thing in a language - just because it does the same thing does not make it illegal (though it can make the language more confusing!) – user1445967 May 07 '13 at 21:48
0

I believe that they left it in because it can increase code readability. Even if nothing should be done for a case you may still want to let people know that the case is important.

aaronman
  • 18,343
  • 7
  • 63
  • 78