9

According to my scientific Java experimentation, int x = 0; is equivalent to int x = 0;; which is equivalent to int x = 0;;;;;;;;;;;;;;;

  1. Why does Java allow for this? Does it have any practical application?
  2. Are each of these just empty statements? Do they actually take up any extra processing time during runtime? (I would assume they're just optimized out?)
  3. Do other languages do this? I'm guessing it's something inherited from C, like a lot of things in Java. Is this true?
Tim
  • 4,295
  • 9
  • 37
  • 49
  • I can't think of a language that doesn't allow empty statements (as long as it's possible to write them in the first place.) – trutheality May 08 '12 at 03:14
  • @trutheality, Ada does not allow empty statements. To explicitly indicate an empty statement, you write ‘null’. See http://archive.adaic.com/standards/83rat/html/ratl-03-07.html for an example. – Chris Page May 08 '12 at 08:45

4 Answers4

21

The extra semicolons are treated as empty statements. Empty statements do nothing, so that's why Java doesn't complain about it.

Jordonias
  • 5,778
  • 2
  • 21
  • 32
18

As Jake King writes, you can produce empty statements to do nothing in a loop:

while (condition);

but to make it obvious, you would write

while (condition)
    ;

or even better:

while (condition)
/** intentionally empty */
    ;

or even better, as Michael Kjörling pointed out in the comment,

while (condition)
{
    /** intentionally empty */
}

More often, you see it in for-statements for endless loops:

for (;;)

or only one empty statement

for (start;;) 
for (;cond;) 
for (;;end) 

Another thing you can do, is, to write a program, once with one, and once with 2 semicolons:

public class Empty
{
    public static void main (String args[])
    {
        System.out.println ("Just semicolons");;
    }
}

Compile it, and run list the size of byte code (identic) and do an md5sum on the bytecode (identic).

So in cases, where the semantics aren't changed, it is clearly optimized away, at least for the 1.6-Oracle compiler I can say so.

user unknown
  • 35,537
  • 11
  • 75
  • 121
  • C can even do `while(condition);` which is also executed as a statement. – Jesvin Jose May 08 '12 at 06:00
  • In the very rare cases that one needs an empty while loop statement-block, I find it better to write it as some incarnation of `while(condition) { }` rather than `while(condition);` (a comment thrown in is another good way to do it). The semicolon can easily be overlooked, but the braces are explicit. **Also**, while I won't say to not use a language feature because someone might not know it, a seemingly errant statement terminator is a mental roadblock, which is often best avoided in order to facilitate understanding of the code. – user May 08 '12 at 07:44
7

Yes, they are empty statements, which don't do anything at all. They are optimized out by the compiler, but in some cases this empty statement actually does something, doing the same thing as a set of empty braces ({}). They are inherited from C syntax, but they have few uses in Java. In C, sometimes doing something like this was useful:

while (condition);

This will loop until condition is false, preventing code from progressing. However, this is discouraged in modern code, and shouldn't ever really be used in Java. However, the empty statement does count as a statement, just a useless one, so constructs like this:

if (condition);
    doSomething();

....may cause somewhat baffling results. The if statement will call the empty statement, not the method, so the method will always be called. Just a caveat to keep in mind.

Alexis King
  • 43,109
  • 15
  • 131
  • 205
  • +1, but I am pretty sure the compiler optimizes (removes) empty statements. – Jeremy May 08 '12 at 02:48
  • @Jeremy Not so, the empty statements are left in since they do, in fact, do something. They technically count as statements, they just do nothing. That's different from full removal of the statements themselves. – Alexis King May 08 '12 at 02:51
  • 3
    Compiling [these two classes](https://www.refheap.com/paste/2645) produces the exact same bytecode (with exception of the class name). The semi-colon at the end of `while (true);` is not an empty statement. It terminates the while loop with out a block. – Jeremy May 08 '12 at 02:55
  • @Jeremy Fair enough. It would appear I am wrong. Admittedly, I don't know where I got that information, but somewhere out there, someone has provided false information. Oh well. – Alexis King May 08 '12 at 02:57
  • @Jeremy I didn't, sorry if it sounded like I was. Thanks for the correction. :) – Alexis King May 08 '12 at 03:01
  • @JeremyHeiler "The semi-colon at the end of while (true); is not an empty statement. It terminates the while loop with out a block" - as per Java Language Specification, this is definitely wrong. `while` statement must end with another statement, there are no exceptions. Whatever semicolons it has, they don't belong to the `while` statement. This is a strange dispute, though, empty statements simply produce nothing in byte code, so it is rather weird to talk about their retention or removal. – Malcolm May 08 '12 at 09:09
  • @Malcolm, My point *was* that empty statements don't exist in bytecode. Perhaps my reasoning was a bit off, but I got the impression that Jake was saying empty statements produced bytecode. anyway, thanks for forcing me to look it up! [Here's the reference for anybody who cares](http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.12) – Jeremy May 08 '12 at 13:23
  • @JeremyHeiler Yes, my correction is only about the language. It's great you've provided a link, it is exactly what I referred to. The answer still looks a little odd to my mind. I wouldn't say that empty statements are "optimized out", there's simply nothing to remove. – Malcolm May 08 '12 at 15:09
0

One thing to note is that if you do something like this:

public int foo()
{
    return(0);;
}

The compiler will/may complain about an unreachable statement because there's an empty statement after a return. At least with Oracle's 1.6 sdk it does.

Jon Lin
  • 142,182
  • 29
  • 220
  • 220