Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > do loop bug?

Reply
Thread Tools

do loop bug?

 
 
emrefan
Guest
Posts: n/a
 
      08-10-2006
Does this program below indicate to you that there's a bug in java's do
loop. Or is it just one of those many traps that I've fallen into and
I've only got myself to blame? I was expecting the two loops would
behave much the same. Have I been bitten by the optimizer?

public class DoLoopBug {
public static void main( String[] args ) {
int retryCnt = 0;
doLoop1: do {
try {
if (retryCnt < 3)
throw new java.net.ConnectException();
break;
}
catch (Exception e) {
System.out.println( "caught exception; retryCnt=" +
retryCnt );
if (++retryCnt < 20)
continue doLoop1;
}
} while (false);

System.out.println( "after doLoop1, retryCnt = " + retryCnt +
"\n" );

retryCnt = 0;

doLoop2: do {
try {
if (retryCnt < 3)
throw new java.net.ConnectException();
break;
}
catch (Exception e) {
System.out.println( "caught exception; retryCnt=" +
retryCnt );
if (++retryCnt < 20)
continue doLoop2;
}
} while (true); // Here's difference from DoLoop1

System.out.println( "after doLoop2, retryCnt = " + retryCnt );
}
}

 
Reply With Quote
 
 
 
 
Patricia Shanahan
Guest
Posts: n/a
 
      08-10-2006
emrefan wrote:
> Does this program below indicate to you that there's a bug in java's do
> loop. Or is it just one of those many traps that I've fallen into and
> I've only got myself to blame? I was expecting the two loops would
> behave much the same. Have I been bitten by the optimizer?
>
> public class DoLoopBug {
> public static void main( String[] args ) {
> int retryCnt = 0;
> doLoop1: do {
> try {
> if (retryCnt < 3)
> throw new java.net.ConnectException();
> break;
> }
> catch (Exception e) {
> System.out.println( "caught exception; retryCnt=" +
> retryCnt );
> if (++retryCnt < 20)
> continue doLoop1;
> }
> } while (false);
>
> System.out.println( "after doLoop1, retryCnt = " + retryCnt +
> "\n" );
>
> retryCnt = 0;
>
> doLoop2: do {
> try {
> if (retryCnt < 3)
> throw new java.net.ConnectException();
> break;
> }
> catch (Exception e) {
> System.out.println( "caught exception; retryCnt=" +
> retryCnt );
> if (++retryCnt < 20)
> continue doLoop2;
> }
> } while (true); // Here's difference from DoLoop1
>
> System.out.println( "after doLoop2, retryCnt = " + retryCnt );
> }
> }
>



The results I get are:

caught exception; retryCnt=0
after doLoop1, retryCnt = 1

caught exception; retryCnt=0
caught exception; retryCnt=1
caught exception; retryCnt=2
after doLoop2, retryCnt = 3

which is what I expected.

Each continue effectively jumps to its loop's while expression
evaluation. For the first loop, the expression evaluates to false, so it
falls through first time.

For the second loop, the while expression evaluates to true, so it does
another iteration. That goes on until retryCnt reaches 3, and the break
is executed instead of the throw leading to a continue.

If this does not answer your question, perhaps you could explain why you
expected the two loops to behave the same?

Patricia
 
Reply With Quote
 
 
 
 
Mike Schilling
Guest
Posts: n/a
 
      08-10-2006

"Patricia Shanahan" <(E-Mail Removed)> wrote in message
news:65wCg.6665$(E-Mail Removed) nk.net...
> emrefan wrote:
>> Does this program below indicate to you that there's a bug in java's do
>> loop. Or is it just one of those many traps that I've fallen into and
>> I've only got myself to blame? I was expecting the two loops would
>> behave much the same. Have I been bitten by the optimizer?
>>
>> public class DoLoopBug {
>> public static void main( String[] args ) {
>> int retryCnt = 0;
>> doLoop1: do {
>> try {
>> if (retryCnt < 3)
>> throw new java.net.ConnectException();
>> break;
>> }
>> catch (Exception e) {
>> System.out.println( "caught exception; retryCnt=" +
>> retryCnt );
>> if (++retryCnt < 20)
>> continue doLoop1;
>> }
>> } while (false);
>>
>> System.out.println( "after doLoop1, retryCnt = " + retryCnt +
>> "\n" );
>>
>> retryCnt = 0;
>>
>> doLoop2: do {
>> try {
>> if (retryCnt < 3)
>> throw new java.net.ConnectException();
>> break;
>> }
>> catch (Exception e) {
>> System.out.println( "caught exception; retryCnt=" +
>> retryCnt );
>> if (++retryCnt < 20)
>> continue doLoop2;
>> }
>> } while (true); // Here's difference from DoLoop1
>>
>> System.out.println( "after doLoop2, retryCnt = " + retryCnt );
>> }
>> }
>>

>
>
> The results I get are:
>
> caught exception; retryCnt=0
> after doLoop1, retryCnt = 1
>
> caught exception; retryCnt=0
> caught exception; retryCnt=1
> caught exception; retryCnt=2
> after doLoop2, retryCnt = 3
>
> which is what I expected.
>
> Each continue effectively jumps to its loop's while expression
> evaluation.


And both "continue"s are unnecessary, since evaluating the "while" is the
next thing to be done anyway, making mw wonder what the intention of the
code is.


 
Reply With Quote
 
Patricia Shanahan
Guest
Posts: n/a
 
      08-10-2006
Mike Schilling wrote:
> "Patricia Shanahan" <(E-Mail Removed)> wrote in message
> news:65wCg.6665$(E-Mail Removed) nk.net...

....
>> Each continue effectively jumps to its loop's while expression
>> evaluation.

>
> And both "continue"s are unnecessary, since evaluating the "while" is the
> next thing to be done anyway, making mw wonder what the intention of the
> code is.
>
>


I assumed it was an artificial test case, stripped down from a larger
program. I THINK maybe the OP expected the continue to unconditionally
go on to another iteration, regardless of the while. That would not be
equivalent to falling through to the while.

Patricia
 
Reply With Quote
 
Thea
Guest
Posts: n/a
 
      08-10-2006
They both are right.
And... one advice:
*Never ever* use exceptions to control normal program flow.
They serve to handle (as name indicates) exceptional situations while
program execution.
This is their purpose. Exception may mean from "this stupid user
entered some text again when was asked to give a numer" up to
"earthquake on the other end of the world destroyed server" , but
it's always something unusual. Exception means that something has gone
wrong.
Next thing: catch exactly exception that is thrown.
If you throw ConnectException, catch this particular exception. This
way you may get some more useful info.
Also: continue (label).
In this code labels are not necessary because (as said before) they
cause jump to while statement in loop being executed. They would be
useful if you wanted to jump somewhere else. But I *strongy recommend*
*not* to do such jumps. They introduce lots of confusion and are likely
to cause a lots of bugs that will be diffult to debug because of hard
to predict program's behaviour. Whenever you want to make such jump,
think twice is there is really no other way.
Try to keep your code as short and simple as possible.
That's my advice. Take it or leave it - it's up to you.
Thea

Mike Schilling napisal(a):
> "Patricia Shanahan" <(E-Mail Removed)> wrote in message
> news:65wCg.6665$(E-Mail Removed) nk.net...
> > emrefan wrote:
> >> Does this program below indicate to you that there's a bug in java's do
> >> loop. Or is it just one of those many traps that I've fallen into and
> >> I've only got myself to blame? I was expecting the two loops would
> >> behave much the same. Have I been bitten by the optimizer?
> >>
> >> public class DoLoopBug {
> >> public static void main( String[] args ) {
> >> int retryCnt = 0;
> >> doLoop1: do {
> >> try {
> >> if (retryCnt < 3)
> >> throw new java.net.ConnectException();
> >> break;
> >> }
> >> catch (Exception e) {
> >> System.out.println( "caught exception; retryCnt=" +
> >> retryCnt );
> >> if (++retryCnt < 20)
> >> continue doLoop1;
> >> }
> >> } while (false);
> >>
> >> System.out.println( "after doLoop1, retryCnt = " + retryCnt +
> >> "\n" );
> >>
> >> retryCnt = 0;
> >>
> >> doLoop2: do {
> >> try {
> >> if (retryCnt < 3)
> >> throw new java.net.ConnectException();
> >> break;
> >> }
> >> catch (Exception e) {
> >> System.out.println( "caught exception; retryCnt=" +
> >> retryCnt );
> >> if (++retryCnt < 20)
> >> continue doLoop2;
> >> }
> >> } while (true); // Here's difference from DoLoop1
> >>
> >> System.out.println( "after doLoop2, retryCnt = " + retryCnt );
> >> }
> >> }
> >>

> >
> >
> > The results I get are:
> >
> > caught exception; retryCnt=0
> > after doLoop1, retryCnt = 1
> >
> > caught exception; retryCnt=0
> > caught exception; retryCnt=1
> > caught exception; retryCnt=2
> > after doLoop2, retryCnt = 3
> >
> > which is what I expected.
> >
> > Each continue effectively jumps to its loop's while expression
> > evaluation.

>
> And both "continue"s are unnecessary, since evaluating the "while" is the
> next thing to be done anyway, making mw wonder what the intention of the
> code is.


 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      08-10-2006

"Patricia Shanahan" <(E-Mail Removed)> wrote in message
news:9uACg.2388$(E-Mail Removed) k.net...
> Mike Schilling wrote:
>> "Patricia Shanahan" <(E-Mail Removed)> wrote in message
>> news:65wCg.6665$(E-Mail Removed) nk.net...

> ...
>>> Each continue effectively jumps to its loop's while expression
>>> evaluation.

>>
>> And both "continue"s are unnecessary, since evaluating the "while" is the
>> next thing to be done anyway, making mw wonder what the intention of the
>> code is.

>
> I assumed it was an artificial test case, stripped down from a larger
> program. I THINK maybe the OP expected the continue to unconditionally
> go on to another iteration, regardless of the while. That would not be
> equivalent to falling through to the while.


I'm not sure why they were there, which is why I thought it worth pointing
out that they did nothing.


 
Reply With Quote
 
emrefan
Guest
Posts: n/a
 
      08-10-2006
> The results I get are:
>
> caught exception; retryCnt=0
> after doLoop1, retryCnt = 1
>
> caught exception; retryCnt=0
> caught exception; retryCnt=1
> caught exception; retryCnt=2
> after doLoop2, retryCnt = 3
>
> which is what I expected.
>
> Each continue effectively jumps to its loop's while expression
> evaluation. For the first loop, the expression evaluates to false, so it
> falls through first time.


Thank you for responding.

This surprises me! I was expecting the continue to restart the loop
without even looking at the while expression. I need to brush up on
java basics <blush>. Maybe other languages have poisoned me.

> For the second loop, the while expression evaluates to true, so it does
> another iteration. That goes on until retryCnt reaches 3, and the break
> is executed instead of the throw leading to a continue.
>
> If this does not answer your question, perhaps you could explain why you
> expected the two loops to behave the same?


Well, I used such a strange construct in the real thing because I
wanted to retry some servlet accessing operation if a
java.net.ConnectException happened. And indeed this exception happened
quite often for a particular customer who was running the relevant
applet. It did not happen each and every time for this customer and
other customers were not suffering the same problem - at least not
frequently enough for them to raise an issue with us.

You explanation is perfectly clear to me. But the "continue to the
while expression" bit trapped me up.

 
Reply With Quote
 
emrefan
Guest
Posts: n/a
 
      08-10-2006

Patricia Shanahan wrote:
> Mike Schilling wrote:
> > "Patricia Shanahan" <(E-Mail Removed)> wrote in message
> > news:65wCg.6665$(E-Mail Removed) nk.net...

> ...
> >> Each continue effectively jumps to its loop's while expression
> >> evaluation.

> >
> > And both "continue"s are unnecessary, since evaluating the "while" is the
> > next thing to be done anyway, making mw wonder what the intention of the
> > code is.

>
> I assumed it was an artificial test case, stripped down from a larger
> program. I THINK maybe the OP expected the continue to unconditionally
> go on to another iteration, regardless of the while. That would not be
> equivalent to falling through to the while.


You are right, what I posted was just a test program to illustrate a
point. And you guessed right, I did expect the continue to
unconditionally go on to another iteration.
Searched the net for a replacement goto construct in java and I found
that "There: do { ... continue There } while (false)" bit of code and
promptly used it without much thought. First timed I used the "do
loop", I admit.

 
Reply With Quote
 
emrefan
Guest
Posts: n/a
 
      08-10-2006

Mike Schilling wrote:
> "Patricia Shanahan" <(E-Mail Removed)> wrote in message
> news:9uACg.2388$(E-Mail Removed) k.net...
> > Mike Schilling wrote:
> >> "Patricia Shanahan" <(E-Mail Removed)> wrote in message
> >> news:65wCg.6665$(E-Mail Removed) nk.net...

> > ...
> >>> Each continue effectively jumps to its loop's while expression
> >>> evaluation.
> >>
> >> And both "continue"s are unnecessary, since evaluating the "while" is the
> >> next thing to be done anyway, making mw wonder what the intention of the
> >> code is.

> >
> > I assumed it was an artificial test case, stripped down from a larger
> > program. I THINK maybe the OP expected the continue to unconditionally
> > go on to another iteration, regardless of the while. That would not be
> > equivalent to falling through to the while.

>
> I'm not sure why they were there, which is why I thought it worth pointing
> out that they did nothing.


I used such a do loop construct because that I was what I found while
googling. Didn't realize I could do without the label. Now that I've
given it a thought, I guess maybe some people want to use a label to
show what is being continued. I personally would have used a comment
after the "continue" to get the same readability result if I had known
that the label wasn't necessary.

 
Reply With Quote
 
Mike Schilling
Guest
Posts: n/a
 
      08-10-2006

"emrefan" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ups.com...
>
> Well, I used such a strange construct in the real thing because I
> wanted to retry some servlet accessing operation if a
> java.net.ConnectException happened. And indeed this exception happened
> quite often for a particular customer who was running the relevant
> applet. It did not happen each and every time for this customer and
> other customers were not suffering the same problem - at least not
> frequently enough for them to raise an issue with us.
>
> You explanation is perfectly clear to me. But the "continue to the
> while expression" bit trapped me up.


If you're loooking for a construct that says "retry if an exception
happened", here's a thought:

boolean done = false;
while (!done)
{
try
{
...
done = true;
}
catch (Exception ex)
{
...
}
}

This will exit the loop only if the code in the try block throws no
exceptions. Of course, you can tinker with it to limit the number of
retries, say

boolean done = false;
int retryCount = 0;
while (!done && retryCount < 3)
{
try
{
...
done = true;
}
catch (Exception ex)
{
...
retryCount++;
}
}





 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
Getting a loop to activate a loop above it Byte Python 4 03-24-2006 03:04 AM
Condition outside loop or separate loop for different condition? - Java 12 06-15-2005 08:50 AM
while loop in a while loop Steven Java 5 03-30-2005 09:19 PM
Loop the loop... =?Utf-8?B?VGltOjouLg==?= ASP .Net 2 02-16-2005 12:21 PM



Advertisments