By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,619 Members | 1,534 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,619 IT Pros & Developers. It's quick & easy.

nested while - how to go to the beginning of the first while?

P: n/a
I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}
Nov 15 '05 #1
Share this Question
Share on Google+
36 Replies


P: n/a


invni wrote:
I have a nested while. How do I go from the inner while to the
beginning of the outer while? I would hate to tell you how.
Can this be done without using goto?


What do you mean? Are you kidding? I have never come across a dialect
of
C that gives you while_# sort of keywords.Better post some real,
compile-able code, and we can bargain.Most often code that craves for a
goto,
needs a serious surgery.

[the garbage van just took your code away...]

You might find the following article handy:
http://groups.google.co.in/group/com....c/browse_frm/

thread/1f70380413394ff7/09a791583ae54898?q=goto&rnum=1&hl=en#09a791583ae54 898

Suman.

Nov 15 '05 #2

P: n/a
On Sat, 25 Jun 2005 05:12:16 -0400, invni <in***@ms37.hinet.net>
wrote:
I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}


Assuming the above is pseudocode, I suspect that you could use a
combination of break and continue. Here is a trivial sample that
makes decisions based on the value of a char variable named ch and a
counter.

int main(void)
{
char ch = 'Y';
int counter = 0;
while(ch == 'Y')
{
puts("Beginning of outer loop");
while(true)
{
puts("Beginning of inner loop");
if(ch == 'N')
break;
else
ch = 'N';
puts("End of inner loop");
}
if(ch == 'N')
{
if(counter++ == 0)
ch = 'Y';
continue;
}
puts("End of outer loop");

}
printf("Good-bye\n");
}

Output:
Beginning of outer loop
Beginning of inner loop
End of inner loop
Beginning of inner loop
Beginning of outer loop
Beginning of inner loop
End of inner loop
Beginning of inner loop
Good-bye

Note that it skips from beginning of the inner loop to the beginning
of the outer loop. HTH.
--

Best wishes,

Bob
Nov 15 '05 #3

P: n/a
Robert W Hand wrote:
On Sat, 25 Jun 2005 05:12:16 -0400, invni <in***@ms37.hinet.net>
wrote:

I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}

Assuming the above is pseudocode, I suspect that you could use a
combination of break and continue. Here is a trivial sample that
makes decisions based on the value of a char variable named ch and a
counter.

int main(void)
{
char ch = 'Y';
int counter = 0;
while(ch == 'Y')
{
puts("Beginning of outer loop");
while(true)
{
puts("Beginning of inner loop");
if(ch == 'N')
break;
else
ch = 'N';
puts("End of inner loop");
}
if(ch == 'N')
{
if(counter++ == 0)
ch = 'Y';
continue;
}
puts("End of outer loop");

}
printf("Good-bye\n");
}

Output:
Beginning of outer loop
Beginning of inner loop
End of inner loop
Beginning of inner loop
Beginning of outer loop
Beginning of inner loop
End of inner loop
Beginning of inner loop
Good-bye

Note that it skips from beginning of the inner loop to the beginning
of the outer loop. HTH.


I got the idea. Thanks.
Nov 15 '05 #4

P: n/a
invni wrote:

I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}


I think it is instructive that you need labels and a precise
definition to describe what you want. The above is not at all
precise.

lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}

can be replaced with:

int flag;

while (c1) {
....
flag = 0;
while (c2) {
....
if (c3) {
flag = 1; break;
}
....
}
if (flag) continue;
....
}

which lacks the clarity and simplicity of the goto version. When
appropriate, just use goto.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 15 '05 #5

P: n/a
On Sat, 25 Jun 2005 13:36:52 +0000, CBFalconer wrote:
invni wrote:

I have a nested while. How do I go from the inner while to the beginning
of the outer while? Can this be done without using goto?
[snip] I think it is instructive that you need labels and a precise definition
to describe what you want. The above is not at all precise.

lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}
}
can be replaced with:

int flag;

while (c1) {
....
flag = 0;
while (c2) {
....
if (c3) {
flag = 1; break;
}
....
}
if (flag) continue;
....
}
}
which lacks the clarity and simplicity of the goto version. When
appropriate, just use goto.


I second that opinion. Goto is justly maligned as often creating horrible
complexity, however its ability in certain circumstances to reduce
complexity is often overlooked.

This is one example of entirely appropriate and effective goto usage;
another is providing a common exit point to a function with nested loops:

int some_func(void)
{
while (c1) {
...
if (fatal1)
goto common_exit;
...
while (c2) {
...
if (fatal2)
goto common_exit;
...
}
}
return 0;
common_exit:
do_cleanup();
return 1;
}

Nov 15 '05 #6

P: n/a

"CBFalconer" <cb********@yahoo.com> wrote

which lacks the clarity and simplicity of the goto version. When
appropriate, just use goto.

You're right, except that some people have got the idea into their heads
that goto is the root of all evil. (It can make over-long functions messier
still.)
Often its easier just to write a slightly worse function without goto than
enage in religious wars with someone who might be intent on stirring up
trouble.
Nov 15 '05 #7

P: n/a
On Sat, 25 Jun 2005 13:36:52 +0000, CBFalconer wrote:
invni wrote:

I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}
I think it is instructive that you need labels and a precise
definition to describe what you want. The above is not at all
precise.

lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}


A good rule for using goto is use them when they are the best tool for the
job. It turns out that that is fairly rare but it is sometimes the case.

A good secondary rule is that if you use goto don't jump backwards, and in
effect create loops without explicit loop constructs. The old "spaghetti
code" syndrome uis much more difficult to create if you don't jump
backwards. I've only encountered one useful exception to this rule, and
that is implementing finite state machines. That works because FSMs
provides their own type of code structure (and hence a framework for
readability) but one that is different to the normal structured
programming block model. The code above is better written as

while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....

lbl1: ;
}
can be replaced with:

int flag;

while (c1) {
....
flag = 0;
while (c2) {
....
if (c3) {
flag = 1; break;
}
....
}
if (flag) continue;
....
}

which lacks the clarity and simplicity of the goto version. When
appropriate, just use goto.


It can be written without gotos or flag variables:

while (c1) {
....
for (;;) {
if (!c2) {
....
break;
}
....
if (c3) break;
....
}
}

although I don't claim this is better.

Lawrence

Nov 15 '05 #8

P: n/a
invni wrote:
I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}


You can probably restructure your code to make it simpler. Give a more
detailed example of what you're trying to do.
Nov 15 '05 #9

P: n/a
In article <KJ*********************@newsc.telia.net>,
akarl <fu********@comhem.se> wrote:
invni wrote:
I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}


You can probably restructure your code to make it simpler. Give a more
detailed example of what you're trying to do.


There was a discussion here (started by yours truly) of the merits of
"break n" (which exists in Bourne and Bourne-like shells). The concensus
was that it was a bad idea and that a (well timed and well placed) goto
should be used instead.

The problem, however, is if your organization forbids goto.

<OT>
Or, if you are not programming in C, but in some similar language, such as
AWK or Pascal (*) or whatever that doesn't have gotos at all.

(*) I know some versions of Pascal do have goto, but my understanding is
that the pure form (of a language that was specifically invented to argue
the case that goto [like drugs, mmkay] is bad) does not.

Nov 15 '05 #10

P: n/a
On Sat, 25 Jun 2005 05:12:16 -0400, invni <in***@ms37.hinet.net>
wrote:
I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

while_1()
{
some codes here
while_2()
{
if true go to the beginning of while_1
}
some codes here
}


The question I have is whether you want to do it in a sane way or in
an insane way. If the latter, look up Duff's device.
Richard Harter, cr*@tiac.net
http://home.tiac.net/~cri, http://www.varinoma.com
Save the Earth now!!
It's the only planet with chocolate.
Nov 15 '05 #11

P: n/a
"Kenny McCormack" <ga*****@yin.interaccess.com> wrote in message
news:d9**********@yin.interaccess.com...
Or, if you are not programming in C, but in some similar language, such as
AWK or Pascal (*) or whatever that doesn't have gotos at all.

(*) I know some versions of Pascal do have goto, but my understanding is
that the pure form (of a language that was specifically invented to argue
the case that goto [like drugs, mmkay] is bad) does not.


Your understanding of Pascal is seriously flawed, standard Pascal does
indeed have a goto statement.

Similarly, I have read in some publication or other that C does not have a
goto. One side effect of the information explosion is the concurrent
disinformation explosion.

Standard Pascal does not have, however, break, continue and the premature
return of C which all serve to minimize the use of goto..
Nov 15 '05 #12

P: n/a
In article <3i************@individual.net>,
osmium <r1********@comcast.net> wrote:
"Kenny McCormack" <ga*****@yin.interaccess.com> wrote in message
news:d9**********@yin.interaccess.com...
Or, if you are not programming in C, but in some similar language, such as
AWK or Pascal (*) or whatever that doesn't have gotos at all.

(*) I know some versions of Pascal do have goto, but my understanding is
that the pure form (of a language that was specifically invented to argue
the case that goto [like drugs, mmkay] is bad) does not.


Your understanding of Pascal is seriously flawed, standard Pascal does
indeed have a goto statement.


Your ability to comprehend conversational English is "seriously flawed",
since otherwise you'd realize how dumb your post sounds.

Nov 15 '05 #13

P: n/a
"Kenny McCormack" <ga*****@yin.interaccess.com> wrote in message
news:d9**********@yin.interaccess.com...
In article <3i************@individual.net>,
osmium <r1********@comcast.net> wrote:
"Kenny McCormack" <ga*****@yin.interaccess.com> wrote in message
news:d9**********@yin.interaccess.com...
Or, if you are not programming in C, but in some similar language, such
as
AWK or Pascal (*) or whatever that doesn't have gotos at all.

(*) I know some versions of Pascal do have goto, but my understanding is
that the pure form (of a language that was specifically invented to
argue
the case that goto [like drugs, mmkay] is bad) does not.


Your understanding of Pascal is seriously flawed, standard Pascal does
indeed have a goto statement.


Your ability to comprehend conversational English is "seriously flawed",
since otherwise you'd realize how dumb your post sounds.


"Some versions" and "does not" sounded to me like you were discussing a real
language. I see now that you were addressing the subject of a language that
someone could conceivably propose, or even write, some time. Would you
agree that this sentence, which doesn't mention Pascal, was a better
representation of what you meant?

"My understanding is that the pure form of a language specifically invented
to argue that goto was bad would not have a goto?"
Nov 15 '05 #14

P: n/a
In article <3i************@individual.net>,
osmium <r1********@comcast.net> wrote:
....
"Some versions" and "does not" sounded to me like you were discussing
a real language. I see now that you were addressing the subject of
a language that someone could conceivably propose, or even write, some
time. Would you agree that this sentence, which doesn't mention Pascal,
was a better representation of what you meant?

"My understanding is that the pure form of a language specifically
invented to argue that goto was bad would not have a goto?"


I'm OK with this.

Nov 15 '05 #15

P: n/a
> From: CBFalconer <cb********@yahoo.com>
lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}
From: Lawrence Kirby <lk****@netactive.co.uk>
while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....

lbl1: ;
} Note that both samples of code jump from inside a block to somewhere
outside that block. (One jumps out from two blocks, while the other
jumps out from the inner block while remaining in the outer block.)
Neither is *really* jumping backwards. The one that jumps out two
levels is really re-starting the outer block. A restart is not
*exactly* the same thing as a backwards jump, although I'm probably
shaving closely to note any difference here.

There's an advantage to the second method, of never jumping even
seemingly backwards. Consider the following *wrong* code: while (c1) {
lbl1: ;
....
while (c2) {
....
if (c3) goto lb1;
....
}
....

}

Note that the outer loop is re-started except that the condition for it
is not re-tested here. This is not the same semantics as the first
examples where it's always re-tested after the jump, and horrible bugs
can happen this bad way.

Note: The one thing you should *never* do, not *ever* *ever*, is jump
from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)

Note that at the machine level, jumping from inside one block to inside
an unrelated block is done all the time, namely when returning from a
function that was called. And if you're working on a really primitive
CPU that doesn't even have a return instruction, so you have to emulate
it by explicitly popping the return address off a stack and using it to
perform an indirect-address jump, then the jump into the calling block
is quite explicit. So my statement above does not apply to
machine-language returns, whether via return instruction or via
emulation of such, OK?

I was thinking a little earlier about how my Distributed Java
instructor said we need to learn how to drive a stick shift to
understand what's really happening before we drive an automatic, so we
needed to manually write SQL via JDBC/ODBC, and manually call servlets,
and manually do RMI, before we could finally drive the J2EE EJB
automatic! If this philosophy were carried to the extreme, we should
all be required to write machine-language code, then assembly-language
code for a machine that doesn't even have a return instruction so we
understand what's really happening, and then write assembly language
code for a regular machine with a fine return instruction, and finally
we can use C or other ordinary programming language. I was thinking how
much fun it'd be to write such a machine/assembly-language emulator for
beginning students to play with. Having it totally interactive with
nice GUI instead of physical toggle switches on front panel would make
it more edudational and less of a pain to use. Any comments from the
rest of you-all? Knuth had something like this in his books, except
there wasn't a Web-accessible emulator to play with, so you can think
of this as a modern version of Knuth's "Mix machine". Hmm, actually
there should be a wider range of options, all the way down below
machine language to state machines that emulate a computer, to logic
gates that build a state machine, to transistor circuits that build a
logic gate. The student could select which level of abstration to work
on at any given time. At the high end of the scale, above
function-calling would be lexical closures which are used to build OOP.
Hmm, should I copy this to comp.programming?
Nov 15 '05 #16

P: n/a
Robert Maas, see http://tinyurl.com/uh3t wrote:
Note: The one thing you should *never* do, not *ever* *ever*, is jump
from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)


Partial loop unrolling or jumping into a do....while loop might
give you justifyable examples. No, I do not advocate it.
BTW: See Duff's device for some (not-goto) inspiration on that matter.

Cheers
Mihcael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #17

P: n/a
"Robert Maas, see http://tinyurl.com/uh3t" wrote:
.... snip ...
Note: The one thing you should *never* do, not *ever* *ever*, is
jump from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)


Knuth did, over 30 years ago. Try:

<http://pplab.snu.ac.kr/courses/PL2001/papers/p261-knuth.pdf>

(about 3 MB, a scan of his paper on care and feeding of goto)

Computing Surveys, Vol 6, No. 4, December 1974

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Nov 15 '05 #18

P: n/a
On Tue, 28 Jun 2005 15:07:32 -0700, Robert Maas, see
http://tinyurl.com/uh3t wrote:
From: CBFalconer <cb********@yahoo.com>
lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}
From: Lawrence Kirby <lk****@netactive.co.uk>
while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....

lbl1: ;
} Note that both samples of code jump from inside a block to somewhere
outside that block. (One jumps out from two blocks, while the other
jumps out from the inner block while remaining in the outer block.)
Neither is *really* jumping backwards.


One is precisely jumping backwards because it is jumping to a label
earlier on in the source code.
The one that jumps out two
levels is really re-starting the outer block.
In effect by creating an extra loop without an explicit looping construct.
This is almost always a bad idea.
A restart is not
*exactly* the same thing as a backwards jump, although I'm probably
shaving closely to note any difference here.
It doesn't have to do anything different, the forward jump I suggested has
the same overall effect. The important thing is how it is presented.
Structured programming constructs don't do anything you can't do with
conditional gotos, it is simply a better means of presentation and
conceptualisation.
There's an advantage to the second method, of never jumping even
seemingly backwards. Consider the following *wrong* code:
while (c1) {
lbl1: ;
....
while (c2) {
....
if (c3) goto lb1;
....
}
....

} Note that the outer loop is re-started except that the condition for it
is not re-tested here. This is not the same semantics as the first
examples where it's always re-tested after the jump, and horrible bugs
can happen this bad way.


Yes, that's another example of why backwards jumps are a bad idea.
Note: The one thing you should *never* do, not *ever* *ever*, is jump
from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)
Yes, that's evil too.

Note that at the machine level, jumping from inside one block to inside
an unrelated block is done all the time, namely when returning from a
function that was called. And if you're working on a really primitive
CPU that doesn't even have a return instruction, so you have to emulate
it by explicitly popping the return address off a stack and using it to
perform an indirect-address jump, then the jump into the calling block
is quite explicit. So my statement above does not apply to
machine-language returns, whether via return instruction or via
emulation of such, OK?


It is a matter of the readability of the code. For compiler generated code
that doesn't have to be readable it isn't important. For hand written
assembly which may have to be read and maintained it is certainly an issue.

Lawrence
Nov 15 '05 #19

P: n/a
CBFalconer wrote:
"Robert Maas, see http://tinyurl.com/uh3t" wrote:

... snip ...
Note: The one thing you should *never* do, not *ever* *ever*, is
jump from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)

Knuth did, over 30 years ago. Try:

<http://pplab.snu.ac.kr/courses/PL2001/papers/p261-knuth.pdf>

(about 3 MB, a scan of his paper on care and feeding of goto)

Computing Surveys, Vol 6, No. 4, December 1974


I get a 404 on the above URL; do you perchance know an alternative
location where I can get the paper?

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #20

P: n/a
Michael Mair wrote:
CBFalconer wrote:
"Robert Maas, see http://tinyurl.com/uh3t" wrote:

... snip ...
Note: The one thing you should *never* do, not *ever* *ever*, is
jump from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)


Knuth did, over 30 years ago. Try:

<http://pplab.snu.ac.kr/courses/PL2001/papers/p261-knuth.pdf>

(about 3 MB, a scan of his paper on care and feeding of goto)

Computing Surveys, Vol 6, No. 4, December 1974


I get a 404 on the above URL; do you perchance know an alternative
location where I can get the paper?


No. Just that I recorded that that is where I got it. I imagine
Knuth may have it on his pages somewhere.

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Nov 15 '05 #21

P: n/a
CBFalconer wrote:
Michael Mair wrote:
CBFalconer wrote:
"Robert Maas, see http://tinyurl.com/uh3t" wrote:

... snip ...
Note: The one thing you should *never* do, not *ever* *ever*, is
jump from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)

Knuth did, over 30 years ago. Try:

<http://pplab.snu.ac.kr/courses/PL2001/papers/p261-knuth.pdf>

(about 3 MB, a scan of his paper on care and feeding of goto)

Computing Surveys, Vol 6, No. 4, December 1974


I get a 404 on the above URL; do you perchance know an alternative
location where I can get the paper?


No. Just that I recorded that that is where I got it. I imagine
Knuth may have it on his pages somewhere.


Had some more time; Knuth's Bibliography says
\p P67. Structured programming with {\bf go to} statements.
{\sl Computing Surveys\/ \bf 6} (December 1974), 261--301. Reprinted
with revisions in {\sl Current Trends in Programming Methodology},
Raymond T. Yeh, ed., {\bf 1} (Englewood Cliffs, N.J.: Prentice-Hall,
1977), 140--194; {\sl Classics in Software Engineering}, Edward Nash
Yourdon, ed.\ (New York: Yourdon Press, 1979), 259--321. Reprinted with
``final'' revisions as Chapter~2 of {\sl Literate Programming\/}
(see under Books).
However, it seems to be nowhere for free, so I went back to the
original site and searched some more; the paper has moved:
<http://pplab.snu.ac.kr/courses/adv_pl04/papers/p261-knuth.pdf>

Thanks for pointing me towards this article :-)
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #22

P: n/a
Michael Mair wrote:
.... snip ...
However, it seems to be nowhere for free, so I went back to the
original site and searched some more; the paper has moved:
<http://pplab.snu.ac.kr/courses/adv_pl04/papers/p261-knuth.pdf>

Thanks for pointing me towards this article :-)


Now maybe someone will find it again later. They are certainly
moving it about.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 15 '05 #23

P: n/a

Robert Maas, see http://tinyurl.com/uh3t wrote:
Note: The one thing you should *never* do, not *ever* *ever*, is jump
from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)


The (in)famous Duff's Device does this, in a strange
way, but more interesting is:

http://tinyurl.com/2452h/dbldum.htm

Many will disparage the software at URL above,
but talk is cheap and *no one* during the 15 years I've
posted this code on Usenet has ever managed
to produce a "better" version (or *any* version)
of the routine without GOTO.

(Most of the disparaging comments have come
from people who obviously made no effort to
understand the code or even read the comments.
Let's see if comp.lang.c has improved over the
years....)

James Dow Allen

Nov 15 '05 #24

P: n/a
On Thu, 30 Jun 2005 22:18:37 -0700, jdallen2000 wrote:

Robert Maas, see http://tinyurl.com/uh3t wrote:
Note: The one thing you should *never* do, not *ever* *ever*, is jump
from outside a loop to inside a loop, or even into a block.
(If anyone can think of a valid example of such, please post now!)
The (in)famous Duff's Device does this, in a strange
way, but more interesting is:

http://tinyurl.com/2452h/dbldum.htm

Many will disparage the software at URL above,
but talk is cheap and *no one* during the 15 years I've
posted this code on Usenet has ever managed
to produce a "better" version (or *any* version)
of the routine without GOTO.


Well the code license does expressly prohibit the removal of gotos. :-)

The code is sufficiently complex that it would take some effort to
understand what it is doing and come up with possible alternatives.

I'm not a "goto gestapo", the Nim code is a nice example of using goto.
But I'm not going to accept that goto is the best way of doing something
just because somebody else says so. :-)

The comments say

* Yes, the `goto' won't operate properly unless all the local variables
* are in precisely the right state to make their strange voyage from
* one inner loop to the other. But that's exactly the concept which
* the potential code-maintainer is intended to grasp.
*

Grasping is one thing, verifying is another. The fact is that this sort of
thing (jumping into loops) does make code more difficult to read, it
creates extra coupling between different parts of the code and a whole set
of preconditions that need to be checked.

I'm not convinced that goto is the best approach for this particular
problem. Of course it needs code to "prove" this. Maybe I'll look at it
further at some point. And if I can't find a better approach I'll agree
with you.
(Most of the disparaging comments have come
from people who obviously made no effort to
understand the code or even read the comments.
Let's see if comp.lang.c has improved over the
years....)


I hope "improve" doesn't mean that people can't argue about it. :-)

Lawrence

Nov 15 '05 #25

P: n/a
Lawrence Kirby wrote:
On Thu, 30 Jun 2005 22:18:37 -0700, jdallen2000 wrote:

http://tinyurl.com/2452h/dbldum.htm
The comments say

* Yes, the `goto' won't operate properly unless all the local variables
* are in precisely the right state to make their strange voyage from
* one inner loop to the other. But that's exactly the concept which
* the potential code-maintainer is intended to grasp.
*
Grasping is one thing, verifying is another. The fact is that this sort of
thing (jumping into loops) does make code more difficult to read, it
creates extra coupling between different parts of the code and a whole set
of preconditions that need to be checked.


Yes, but there already is extremely tight coupling between the two
loops,
since one precisely undoes what the other does. There may seem to be
a lot of local variables, but each one has a clear direct meaning in
its
context (number of cards played to the trick, which player led, etc.)

I'll agree that the code will be harder to grasp than a typical routine
of
the same length, but that isn't the proper criterion. Compare it with
the readability of the alternate routine, however long, that *solves
the
same problem.*
I'm not convinced that goto is the best approach for this particular
problem. Of course it needs code to "prove" this. Maybe I'll look at it
further at some point. And if I can't find a better approach I'll agree
with you.


Thank you, Lawrence. FWIW your comments are more reasoned
and objective than any responses received to this in the past.

The term "best" approach is ambiguous: do we seek speed or
readability? The algorithm can be factored into recursive functions
(which may or not be more readable) but which will probably be clumsy
and slow. Certain idiosyncrasies of this particular problem (e.g.
player sequencing depends on prior trick) weaken the case of
alternatives
to the wierd goto but, though perhaps I shouldn't admit it, I often
adopt this wierd-goto model to hack out other backtrackers quickly.
(Most of the disparaging comments have come
from people who obviously made no effort to
understand the code or even read the comments.
Let's see if comp.lang.c has improved over the
years....)


I hope "improve" doesn't mean that people can't argue about it. :-)


Of course not! I'd love to see comp.lang.c'ers come up with the
"proper" alternative. I have psychological trouble doing that myself,
since I already know I like my way best :-)

James Dow Allen

Nov 15 '05 #26

P: n/a
James Dow Allen wrote:
Lawrence Kirby wrote:
jdallen2000 wrote:

http://tinyurl.com/2452h/dbldum.htm

The comments say

* Yes, the `goto' won't operate properly unless all the local
* variables are in precisely the right state to make their
* strange voyage from one inner loop to the other. But
* that's exactly the concept which the potential code-
* maintainer is intended to grasp.

Grasping is one thing, verifying is another. The fact is that
this sort of thing (jumping into loops) does make code more
difficult to read, it creates extra coupling between different
parts of the code and a whole set of preconditions that need to
be checked.


Yes, but there already is extremely tight coupling between the two
loops, since one precisely undoes what the other does. There may
seem to be a lot of local variables, but each one has a clear
direct meaning in its context (number of cards played to the trick,
which player led, etc.)

I'll agree that the code will be harder to grasp than a typical
routine of the same length, but that isn't the proper criterion.
Compare it with the readability of the alternate routine, however
long, that *solves the same problem.*


Luckily I already had a copy of that article, since I won't use the
'unknown destination' tinyurls. I have no great complaint about
the goto, in fact I often recommend it. What that package needs is
the description of its metamorphosis from something
understandable. Even the existance of a (possibly very slow)
top-down crafted solution would help.

A 30 or more year old Knuth article on the use of gotos that I
recommended here (or there) a few days ago did precisely that. It
followed the evolution from a clear to an efficient solution step
by step.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #27

P: n/a
CBFalconer wrote:
jdallen2000 wrote:
http://tinyurl.com/2452h/dbldum.htm
Luckily I already had a copy of that article, since I won't use the
'unknown destination' tinyurls.
Doesn't the ".htm" at the end offer some reassurance?
And anyway, is my reputation so poor here that you
thought *I* was trying to break into your machine?
But point taken, I'll give regular URL in future. (The host
I use is nice in some ways, but has a ridiculously long URL.)
[A] Knuth article ...
followed the evolution from a clear to an efficient solution step
by step.


It's probably obvious that my routine is faster than a
"properly written" alternative. My claim is that it may also
be *clearer* once one escapes the mental block of disliking
the peculiar structure. (The alternative will be clumsy.)

Admittedly I should add detailed comments and rewrite some
of the long expressions to make this point. But the "cute"
programming examples I show at my website are a low priority
for me, and I've not received much encouragement here.... :-)

James

Nov 15 '05 #28

P: n/a
James Dow Allen <jd*********@yahoo.com> wrote:
CBFalconer wrote:
>> jdallen2000 wrote:
>>> http://tinyurl.com/2452h/dbldum.htm

Luckily I already had a copy of that article, since I won't use the
'unknown destination' tinyurls.


Doesn't the ".htm" at the end offer some reassurance?
And anyway, is my reputation so poor here that you
thought *I* was trying to break into your machine?
But point taken, I'll give regular URL in future. (The host
I use is nice in some ways, but has a ridiculously long URL.)


This is the first time I hear about it. What is the difference
in terms of security between different URLs, be they short or long?
Except that posting tinyurls is not a good idea in itself, the only
problem I can see is that tinyurl.com might be hijacked, but so
might any other homepage.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 15 '05 #29

P: n/a
S.Tobias wrote:
This is the first time I hear about it. What is the difference
in terms of security between different URLs, be they short or long?
Except that posting tinyurls is not a good idea in itself, the only
problem I can see is that tinyurl.com might be hijacked, but so
might any other homepage.


tinyurl.com is a "URL shortening" service - you give it a long, unwieldy
URL and it will "convert" it to a shorter one beginning with
"http://tinyurl.com/".

When you request the tinyurl.com URL, your browser receives and follows
an HTTP 302 redirect to the original, longer URL. Because there is no
"are you sure you want to visit long_url?" confirmation, you're
effectively clicking blind links.

Other "URL shortening" services acknowledge this problem and insert a
time delay or confirmation before redirecting the client (though I can't
think of them off the top of my head).

To James: the .htm should be of no reassurance - browsers will interpret
content based on the HTTP Content-type header they receive, not based on
file extension.

Steve
Nov 15 '05 #30

P: n/a
James Dow Allen wrote:
CBFalconer wrote:
.... snip ...
Luckily I already had a copy of that article, since I won't use
the 'unknown destination' tinyurls.


Doesn't the ".htm" at the end offer some reassurance?
And anyway, is my reputation so poor here that you
thought *I* was trying to break into your machine?
But point taken, I'll give regular URL in future. (The host
I use is nice in some ways, but has a ridiculously long URL.)


No, but when you arrive here you are just another pretty face. You
can always supply both forms. Do check the Knuth quotation. I
think it is now at:

<http://pplab.snu.ac.kr/courses/adv_p104/papers/p261-knuth.pdf>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #31

P: n/a
Stephen Hildrey wrote:
S.Tobias wrote:
This is the first time I hear about it. What is the difference
in terms of security between different URLs, be they short or
long? Except that posting tinyurls is not a good idea in itself,
the only problem I can see is that tinyurl.com might be hijacked,
but so might any other homepage.


tinyurl.com is a "URL shortening" service - you give it a long,
unwieldy URL and it will "convert" it to a shorter one beginning
with "http://tinyurl.com/".

When you request the tinyurl.com URL, your browser receives and
follows an HTTP 302 redirect to the original, longer URL. Because
there is no "are you sure you want to visit long_url?" confirmation,
you're effectively clicking blind links.

Other "URL shortening" services acknowledge this problem and insert
a time delay or confirmation before redirecting the client (though
I can't think of them off the top of my head).

To James: the .htm should be of no reassurance - browsers will
interpret content based on the HTTP Content-type header they
receive, not based on file extension.


Other problems - the tinyurl has a relatively short lifespan. If
you try to follow one from a saved message of an appropriate age,
it just won't work, or will lead elsewhere. The actual URL at
least has a chance of being valid.

Also, since you have no idea where you are going, you can simply be
leaving your return address as a location for some form of bot to
probe. When I am connected my zonealarm log shows something like
1/2 to 10 probes per minute from outside that have been rejected.

The log shows something like 25,000 probes in the past 5 years, or
about 400 per month. Other records show that I am on-line and
connected about 50 mins per month. So that leaves a consistent
probe level of the order of 10 per minute. I am sure some of the
probes may be relatively benign, but the rest are not. Zonealarm
is the one really necessary piece of protection. Other things can
be avoided by a little hygiene, such as rejecting html/mime mail.

I didn't even realize the long term level was that high until I
looked for this reply! And I operate mainly off-line.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #32

P: n/a
In article <11**********************@f14g2000cwb.googlegroups .com>,
James Dow Allen <jd*********@yahoo.com> wrote:

Doesn't the ".htm" at the end offer some reassurance?
No. The content-type is established in the HTTP header
and need not match the file suffix. A malicious
web site can send you activex or JPG files that
are innocuously named "index.html".
And anyway, is my reputation so poor here that you
thought *I* was trying to break into your machine?


I would not fear that so much, but I don't need inappropriate
JPEG's appearing on my screen during work hours. It's usually
not something to fear on comp.lang.c but if one's employer is
strict you need to be careful with slashdot for example.
--
7842++
Nov 15 '05 #33

P: n/a
CBFalconer <cb********@yahoo.com> writes:
invni wrote:

I have a nested while. How do I go from the inner while to the
beginning of the outer while? Can this be done without using goto?

[unclear code snipped]


I think it is instructive that you need labels and a precise
definition to describe what you want. The above is not at all
precise.

lb1: while (c1) {
....
while (c2) {
....
if (c3) goto lb1;
....
}
....
}

can be replaced with:

int flag;

while (c1) {
....
flag = 0;
while (c2) {
....
if (c3) {
flag = 1; break;
}
....
}
if (flag) continue;
....
}

which lacks the clarity and simplicity of the goto version. When
appropriate, just use goto.


I agree with the commentary, but I think the last sentence does a
disservice to the OP. The reason a 'goto' statement is usually a bad
idea is not that it's a 'goto' but that most often it's symptomatic of
bad program structure. When a situation arises where 'goto' seems
like the best way to write something, usually that means the function
in question is in need of significant revision. The first version
above may be cleaner than the second, but either version should raise
a red flag[*] during code review. Explore alternatives; neither of
the examples above should be accepted unless evidence that a better
alternative can't be found is fairly compelling.

[*] No pun intended. :)
Nov 15 '05 #34

P: n/a
"James Dow Allen" <jd*********@yahoo.com> writes:
CBFalconer wrote:
> jdallen2000 wrote:
>> http://tinyurl.com/2452h/dbldum.htm

[A] Knuth article ...
followed the evolution from a clear to an efficient solution step
by step.


It's probably obvious that my routine is faster than a
"properly written" alternative. My claim is that it may also
be *clearer* once one escapes the mental block of disliking
the peculiar structure. (The alternative will be clumsy.)

Admittedly I should add detailed comments and rewrite some
of the long expressions to make this point. But the "cute"
programming examples I show at my website are a low priority
for me, and I've not received much encouragement here.... :-)


Alright, I'll offer some encouragement. Consider an approach along
the following lines.

void
find_optimal_play(){
... a few local variables ...

... initialize ...

FOREVER {

FOREVER {
play one more card from alternatives
set alternatives for next play
if( at end of trick ){
advance state to next trick
if( one side "won" ) break;
}
}

FOREVER {
if( at start of trick ){
if( at first trick ) return;
regress state to previous trick
}
regress state to previous play
undo effects of card played
if( this side should try other plays ) break;
}
}
}

I coded up something along these lines. The control flow is just what
is shown here: three infinite loops, two break's, one return. The
state of the computation was in a data structure much like the one you
used - a stack of "tricks" with information about alternatives and
cards played. Only a few local variables, and I made essentially no
effort to micro-optimize; for example, the suit led is recalculated
each time through the "advance the state" loop:

suit_led = SUIT( S->card_played[ S->on_lead ] );

Except for the different method of doing control flow, the two
programs use basically the same algorithm. The structured code ran
about 25% faster than your code with goto's.

So I guess I'm encouraging you to reconsider whether this problem is a
good example to illustrate when goto's are clearer or faster. Neither
seems to be true in this particular case.
Nov 15 '05 #35

P: n/a

Tim Rentsch wrote:
Alright, I'll offer some encouragement. Consider an approach
[with] three infinite loops, two break's, one return.... Except for the different method of doing control flow, the two
programs use basically the same algorithm. The structured code ran
about 25% faster than your code with goto's.


Congratulations and thank you!

Would you like to post your code at my site, with whatever
commentary you choose?

James Dow Allen (e-mail jamesdowallen at gmail.com)

Nov 15 '05 #36

P: n/a
> From: Lawrence Kirby <lk****@netactive.co.uk>
The important thing is how it is presented.
I agree. Loops of the FOR or WHILE type, and mappings down sequences
such as are common in Lisp, make it obvious at first glance what kind
of loop is done, compared to a GOTO loop where you have to read the
code carefully to diagonse the various kinds of loops.
Structured programming constructs don't do anything you can't do with
conditional gotos,
Nobody ever said otherwise: It's the converse that is claimed:
Structured programming constructs *prevent* you from using the full
flexibility that GOTO would allow, thereby preventing you from doing
things you shouldn't do anyway and shouldn't even want to do.

On the other hand, tail recursion can be used to emulate GOTO, so
syntactic structured programming doesn't actually prevent you from
writing haywire algorithms.
it is simply a better means of presentation and conceptualisation.


Only if you keep your FOR and WHILE and MAP loops simple. A really
hairy set of nested FOR and WHILE loops full of BREAK and CONTINUE in
all sorts of odd places can end up being as inscrutable as a GOTO
haywire.
Nov 15 '05 #37

This discussion thread is closed

Replies have been disabled for this discussion.