views:

313

answers:

6

Hello,

what behaviour can I expect when I run this code:

do while(testA) {

    // do stuff

} while(testB);

Will it behave like:

do {
    while(testA) {
        // do stuff
    }    
} while(testB);

Or:

if(testA) {
    do {
        // do stuff
    } while(testA && testB);
}

Or something totally unexpected?

I ask this question because I think this is quite ambiguous, and for other people searching on this topic, not because I am lazy to test it out.

+1  A: 

The answer is #1. It will continue to loop as long as testB is satisfied but it will not execute the code if testA is not satisfied.

Pierre-Antoine LaFayette
It is legal syntax (JDK 1.6). So why should it then be illegal code? Please explain.
Pindatjuh
You're right I've tested it and the answer is #1. I've edited my answer.
Pierre-Antoine LaFayette
+2  A: 

"do {} while();" is one construct, while "while(){}" is another.

There is no such thing as "do while"; you are inadvertently nesting them and taking advantage of the fact that {} is optional for single instructions.

In other words, this is legal syntax:

do System.out.println("Hello World") while (true);

And like in if-statements, a block is treated as a single statement.

Which is to say, your first possible answer is the right one, where "while(){}" is the single non-bracketed thing inside the outer "do {} while();"

Sparr
+1  A: 

It behaves like

do {
    while(testA) { 
        // stuff
    }
} while(testB);

So, that block of code is parsed this way:

do {a block of code} while testB is true. Where {a block of code} is the inner while.

It's certainly a bit uncommon to write code like that :)

Andrea Zilio
A: 

I do not think this code is legal.

do while(testA) {

        // do stuff

    } while(testB);
giri
It is. Try it and see.
Michael Myers
+6  A: 

It is equivalent to your first block:

do {
    while(testA) {
        // do stuff
    }    
} while(testB);

The relevant parts of the Java grammar when parsing this are:

DoStatement:
    do Statement while ( Expression ) ;

Statement:
    WhileStatement

WhileStatement:
    while ( Expression ) Statement

Statement:
    Block

Block:
    { BlockStatements_opt }

You can see that the Java compiler will parse this as do <WhileStatement> while ( Expression ) ;. That's the only valid way to parse the code that you wrote.

Keep in mind that it doesn't have any special rule to parse this construct. It just ends up being confusing for a human to read due to the unusual way the do-while loop is written. In normal usage do-while is always written as do { ... } while with explicit curly braces.

John Kugelman
+1  A: 

It works indeed, but the behaviour depends on what conditions your are testing. E.g. this code:

  int i = 2;
  int j = 4;
  do while(j > 0) {
       i--; j--;
       System.out.println("i:" + i + " j:" + j);
 } while(i > 0);

outputs:

i:1 j:3
i:0 j:2
i:-1 j:1
i:-2 j:0

So it works like:

while(j>0) {

}

Whereas by exchanging the variable names:

do while(i > 0) {
    //.. same as above
 } while(j > 0);

The output is:

i:1 j:3
i:0 j:2

It looks like it behaves the same as in the first case (i.e. the first while is considered), but here, the application is not terminating!


Summary:
At the time when testA is not satisfied anymore and testB is also not satisfied, the code works like a normal while(testA){} loop.
But: If, at the time when testA is no longer satisfied, testB is still satisfied, the loop is not executed any more and the script is not terminating. This only applies if the condition of the "outer" loop needs to be changed inside the loop.

Update: And after reading other answer, I realize that this is exactly the behavior of the nested do-while - while loop.
Anyway, lesson learned: Don't use this kind of syntax because it can confuse you ;)

Felix Kling
It's not terminating because once i reaches 0, the inner loop doesn't run anymore -- and therefore j can never reach 0.
Michael Myers
Interesting, this obviously is because the outer `do while` loop will loop, but the content of this `do while` won't loop because the inner loop fails a condition! Thank you for testing.
Pindatjuh