How to "continue" in nested do-while-loop?

J

Jan Schmidt

Hi,

in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct):

--
do
{
// ...
while (y) {
if (z) goto next; //continue outer loop (but check x!)
}
// ...
//A
}
//B
while (x);
--

The question is where to place the "next" label in this construct?
Placing it at A gives me a "label at end of compound statement", placing
it at B gives a "syntax error".

Of course, I could construct things like this:

--
do {
next:
// ...
while (y) {
if (z) {
if (x) goto next; //continue outer loop
else goto afterloop;
}
}
// ...
}
while (x);
afterloop: // ...
--

Or this:

--
do {
// ...
while (y) {
if (z) goto next; //continue outer loop
}
// ...
next:
if (0) {}; //dummy to allow label
}
while (x);
 
G

Guest

Jan said:
Hi,

in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct):

--
do
{
// ...
while (y) {
if (z) goto next; //continue outer loop (but check x!)
}
// ...
//A
}
//B
while (x);
--

The question is where to place the "next" label in this construct?
Placing it at A gives me a "label at end of compound statement", placing
it at B gives a "syntax error".

At A, with a workaround similar to what you describe below.
Of course, I could construct things like this:

--
do {
next:
// ...
while (y) {
if (z) {
if (x) goto next; //continue outer loop
else goto afterloop;
}
}
// ...
}
while (x);
afterloop: // ...

That would work, but it's uglier than the below.
Or this:

--
do {
// ...
while (y) {
if (z) goto next; //continue outer loop
}
// ...
next:
if (0) {}; //dummy to allow label
}
while (x);

You can just use "next: ;". A single semicolon is a statement as well.
But somehow I've got the impression there must be a straight way :)

You'd think so, but this is one of the limitations of C, sorry. Maybe
you can rewrite your code to avoid a need for it, but if you can't,
this is the best you can get.
 
A

ais523

Jan said:
Hi,

in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct): (snip)
Or this:

--
do {
// ...
while (y) {
if (z) goto next; //continue outer loop
}
// ...
next:
if (0) {}; //dummy to allow label
}
while (x);
--

But somehow I've got the impression there must be a straight way :)

TIA, Jan
You have the right idea with your last suggestion. There is a dummy
statement provided for this purpose: use a single semicolon, like this:
do {
/* ... */
while(y) {
if(z) goto next;
}
/* ... */
next: ;
}
while(x);

The semicolon by itself is a statement with no effect.
 
B

Ben Pfaff

Jan Schmidt said:
in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct):

--
do
{
// ...
while (y) {
if (z) goto next; //continue outer loop (but check x!)
}
// ...
//A
}
//B
while (x);
--

The question is where to place the "next" label in this construct?
Placing it at A gives me a "label at end of compound statement", placing
it at B gives a "syntax error".

The C grammar says that a label has to be followed by a
statement. It's the statement that's labeled, not a gap between
statements. The usual dodge is to just put a semicolon after the
label, so that it's labeling the empty statement.

It's not going to work to put it in location B, because
do...while may only contain a single statement (which ordinarily
and in this case is a compound statement).
 
L

loic-dev

Hi Jan,
in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct):

Perhaps I do not understand fully your problem, but why don't you use
simply 'break' statement?

do {
// ....
while (y) {
if (z) break; // go out of that while(y) loop
}
// ...
}
while (x);

HTH,
Loic
 
G

Guest

Hi Jan,
in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work (without a strange workaround construct):

Perhaps I do not understand fully your problem, but why don't you use
simply 'break' statement?

do {
// ....
while (y) {
if (z) break; // go out of that while(y) loop
}
// ... [ XXX ]
}
while (x);

Any statements at the location I marked with [ XXX ] would be executed
with your suggestion, but the idea of "continue" is to go straight to
rechecking the loop condition and to skip everything else.
 
L

loic-dev

Hi Harald,
do {
// ....
while (y) {
if (z) break; // go out of that while(y) loop
}
// ... [ XXX ]
}
while (x);

Any statements at the location I marked with [ XXX ] would be executed
with your suggestion, but the idea of "continue" is to go straight to
rechecking the loop condition and to skip everything else.

Thanks for your explanations... Now, I understand what the problem is
;-)

Cheers,
Loic.
 
L

loic-dev

Hi again,

Ok, now that I do understand your problem, another alternative to your
2nd work-around could be:

do {
// ...
while (y) {
if (z) goto next; //continue outer loop
}
// ...
next:
continue;
}
while (x);

Cheers,
Loic.
 
R

Richard Heathfield

Jan Schmidt said:
Hi,

in a nested do-while-loop structure I would like to "continue" the outer
loop. With goto this should be no problem in while-loops. However, for
do-while I cannot get it to work

do
{
foo();
bar = 0;
while(!bar && baz)
{
quux();

/* At this point, either you want to carry on
processing this loop, or you don't. Set bar accordingly. */

if(!bar)
{
quuy();
}
}
if(!bar)
{
quuz();
}
} while(ribbit);
 
B

Barry

Richard Heathfield said:
Jan Schmidt said:


do
{
foo();
bar = 0;
while(!bar && baz)
{
quux();

/* At this point, either you want to carry on
processing this loop, or you don't. Set bar accordingly. */

if(!bar)
{
quuy();
}
}
if(!bar)
{
quuz();
}
} while(ribbit);

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.

Amazing that on clc it took this long for someone to post
the effective answer - Why not write the code correctly
instead of hack it to work?
 
R

Richard Heathfield

Barry said:

Amazing that on clc it took this long for someone to post
the effective answer -

Well, I actually posted it within two hours of the question being asked. It
seems that it's taken two days for my answer to reach your server, though -
so what is *truly* amazing is how slow some news swervers can be. :)
Why not write the code correctly instead of hack it to work?

Quite so.
 
V

vid512

Amazing that on clc it took this long for someone to post
the effective answer - Why not write the code correctly
instead of hack it to work?
checking same condition twice is correct? in my opinion this is hacking
just to prevent goto. I still wonder why some programmers are afraid of
it. Just like C#ers are afraid of pointers, because they can be
misused.

what's wrong with having label at end of compound statement? This is
clear example where it can be useful.
 
V

vid512

Amazing that on clc it took this long for someone to post
the effective answer - Why not write the code correctly
instead of hack it to work?
checking same condition twice is correct? in my opinion this is hacking
just to prevent goto. I still wonder why some programmers are afraid of
it. Just like C#ers are afraid of pointers, because they can be
misused.

what's wrong with having label at end of compound statement? This is
clear example where it can be useful.
 
R

Richard Bos

Barry said:
Amazing that on clc it took this long for someone to post
the effective answer - Why not write the code correctly
instead of hack it to work?

Because peppering your code with dozens of superfluous variables and
extra ifs is _not_ the correct way to write this code. Perhaps there is
a way to rewrite the OP's code so that it doesn't use goto and maintains
its legibility - but this isn't it.

Richard
 
R

Richard Heathfield

Richard Bos said:

Because peppering your code with dozens of superfluous variables and
extra ifs is _not_ the correct way to write this code.

I didn't use any variables not used by the OP. (I did, however, give them
different names.) It's true that I used one extra condition in the if(),
but in the process I lost a goto and made the code structure clearer.

By all means criticise my code if you wish - that's how we learn, right? -
but please try to keep your criticisms accurate.
Perhaps there is
a way to rewrite the OP's code so that it doesn't use goto and maintains
its legibility - but this isn't it.

It's one way. If you have a better alternative, let's see it. Until then, I
stand by my solution.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top