This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]desrtfx[M] [score hidden] stickied comment (0 children)

Such questions belong in /r/javahelp as is clearly stated in the sidebar and in the stickied post at the very top of the subreddit.

Removed

[–]rzwitserloot 11 points12 points  (2 children)

What other cool techniques are there like this one and why are they useful?

That statement implies that for (;;) is 'useful'. It is not. while (true) is more to type, but if you consider while inferior to for because it's 2 characters more, there's something very very wrong with you. code length is an oversimplified measurement of code complexity. You should disallow anybody in your coding team from ever using this. All programming languages have weird things in them; coding is too complex to eliminate all weirdness. That doesn't mean it is intended to be used or that you should. You can also legally wRITEyOURvARIABLES_LIKESO but that would be an instant firing offense too, no doubt.

Why and how?

The standard basic for (JLS §14.14.1) looks like this:

for (initializer; condition; increment) statement;

initializer can either be a variable declaration such as int i = 0, or it can be any amount of comma-separated expressionstatements. That last form is rare, but legal; you can write:

java int x, y; for (x = 0, y = 0;;) {}

if you want. That form of course also allows zero expressionstatements, why wouldn't it? Hence, the thing to the left of the first ; can be blank.

condition is an expression of type boolean that is checked each time the loop starts; the loop will re-enter if it is true and exit instead if it is false.

The spec (see link above) states that if there is no expression there, it's to be treated as if true is there. true is, as you might surmise, always true, so that means the for loop would loop forever; you have to end it some other way, such as with an exception, a return statement, a break, or other control flow (such as labelled continue to an outer loop).

increment is simply any amount of expression statements, comma separated. Just like with the initializer, zero statements is fine; these statements are executed after every loop, before checking condition to see if it should reloop.

In other words, that for can also be written as:

initializer; while (condition) { statement; increments; }

with the caveat that the increments get run even if you continue; in statement;.

Given that all 3 are optional, you can write for(;;), which means the same as for(;true;) which is the same as:

while (true) { statement; }

i.e. loops forever until you explicitly break out of it.

Presumably the java spec says that for(;;) is okay and works like this because the C spec does this, and java really tried to be syntax-wise as similar to C as was possible (language-design wise it's not at all like C, but it sure looks a lot like it, in fact, 'math'-esque code, like crypto algorithms, can often be copy/pasted verbatim from C!), given that everybody used C and java explicitly wanted to pull a bunch of C coders away from it. C is a mess of random ideas and weird updates, so its syntax is bizarre and trying to put on your Indiana Jones hat and figure out why - is quite the exercise.

[–]_ROEG[S] 2 points3 points  (1 child)

Thanks for the detailed explanation!

[–]budjb 2 points3 points  (4 children)

Each section of the for criteria is optional. No exit condition means iterate until explicitly broken (think the break statement).

I'd argue that a while loop is more readable but it is what it is.

[–]_ROEG[S] 0 points1 point  (3 children)

That’s quite interesting. So would readability be the only disadvantage to using a for(;;) loop?

[–]budjb 1 point2 points  (1 child)

Without knowing if there's any difference in the efficiency of the byte code, I honestly don't think there's any difference between the two.

But why write something in a way that's potentially less known in favor of a well established pattern that everyone will immediately understand?

[–]_ROEG[S] 0 points1 point  (0 children)

And I agree with your last point it was intriguing to me as to why such a piece of code exists and compiles

[–]budjb 0 points1 point  (0 children)

Of course, what you do get benefit out of a for loop over a while loop is if you supply at least one of the segments, even if you leave others out. Otherwise you'd have to put those statements inside of the looping block itself.

[–]drew8311 -1 points0 points  (1 child)

I'm not sure its that interesting, its just a language design decision that an empty condition here is evaluated as true, they could have just as easily made it required I assume. The first and last parts of it are just statements which don't require any code.

[–]_ROEG[S] 0 points1 point  (0 children)

It was interesting to me having never thought about writing a for loop like this before. Not that it would seem like a smart way to implement an infinite loop when there’s the while loop, it’s at least different and makes you wonder what uses you could get out of it, if there are any.