Topic: PROPOSAL: Parameterized return/break/continue for nested loops
Author: sean@delta.com (Sean L. Palmer)
Date: 1996/10/21 Raw View
> I've seen your idea of 'super break' or 'super continue' and
relative-level
> continues/breaks in this thread before. The 'iterate' statement for
looping
> without test sounds novel, but it seems a bit unsafe. (Does an 'iterate'
> statement also skip the 'next' clause in for loops? Overall, it sounds
like
> a good way to start an I/O hang or a fork bomb.)
It would jump past the test and next clauses in a typical for loop. Other
kinds of loops aren't that complicated.
You know how for loops are typically compiled right?
for (init;test;next) { block; }
compiles to the equivalent while-statement with goto:
init;
goto pastnext
while (test) {
next;
pastnext:
block;
beforetest:
}
The iterate statement would branch to pastnext.
The continue statement would instead branch to beforetest.
The iterate statement would always continue the loop. The continue
statement may cause exiting of the loop.
I've found it mostly useful in loops where you're modifying the control
variable inside the loop. It would also enable a kind of open-bottomed do:
do {
if (x) iterate;
if (y) iterate;
if (z) iterate;
} while (false);
> My main problem with relative-level breaks is the maintenance headache
that
> would ensue. Breaking out of N levels makes it much harder to analyze the
> looping behavior for nested loops or when adding a new layer of nesting.
> C++ maintenance is hard enough already; try hunting down which overloaded
> operator gets called in a given context, especially when namespaces are
> involved. At least with 'labeled' breaks/continues it's easier to spot
> where the control transfers to. To make it really easy, you could even
put
> the label at the *end* of the loop. Oh... wait... that's exactly what
goto
> does now.
Problem with goto happens when you have to start hunting through a large
function for the target label to see where it goes. With relative breaks
you know implicitly where it's going. Perhaps actually it would be better
to label the STATEMENT, then break on that label, which would exit the loop
which was so labeled, or continue the loop with the label, etc.. I think
that's what the other guy suggested.
In my language it was a more structured alternative to the goto statement,
which isn't included.
> I don't think maintenance problems get enough attention in C++. It's
still
> a young enough language--one that's only slowly been accepted in many
> places--that more programs are still in the 'building' phase than in the
> 'maintaining' phase. Spend some time reading other people's C++ in the
late
> integration or maintenance phases of a project, and you'll see what I
mean.
> The language solves a lot of C's scalability problems, but introduces
> several of its own. In particular, I know why the Java people outlawed
> operator overloading.
Operator overloading is one of the reasons my code is actually readable.
Would look like crap if it was all function calls. But I see your point.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: sean@delta.com (Sean L. Palmer)
Date: 1996/10/16 Raw View
> HOWEVER, having said all that, I agree that the goto SHOULD be removed,
and
> replaced with (a) structured equivalent(s). That is why I propose
> essentially the naming of compound statements. The compound statement's
> name can be used (including scoping rules) by breaks or continues.
I've designed a language construct that does this. It might be applicable.
The actual keywords would probably get tweaked by the committee and are
unimportant for this discussion.
Introduce new keyword "iterate" which is essentially a continue which
transfers control to a point in the loop which immediately follows the
evaluation of the termination condition. In other words, unconditionally
continue the loop.
Introduce new keyword "super" which can precede any break or continue or
iterate statement. This super keyword causes the break-statement in
question to apply to the loop which contains the loop in which the break
statement appears. Also a valid modifier for break in switch statements,
which I consider to be an outdated mechanism that's error prone by the way.
example:
{
int x=rand(12);
for (int i=0; i<8; ++i) {
for (int j=0; j<i; ++j) {
if (j>x)
super break; //jumps out of the outer for loop.
if (j==x && i==x)
break; //jumps out of the inner for loop
}
}
}
More than one 'super' modifier could be added. An alternative syntax which
I actually think would be better is that break and continue (and iterate)
could be followed by a constant positive integral count which determined
how many levels of loops outward to apply it to, and defaulted to one (the
current loop). So 'break 1;' would be equivalent to the current 'break;',
and 'break 2;' would be equivalent to the 'super break' construct above.
I agree that it would be a nice addition to the language and would allow
the removal of goto altogether, something I consider a good thing, even
though I'm tempted to use it on occasion to minimize redundant code.. that
would be the only practical application of goto if this extended break
feature were added.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/10/17 Raw View
I've seen your idea of 'super break' or 'super continue' and relative-level
continues/breaks in this thread before. The 'iterate' statement for looping
without test sounds novel, but it seems a bit unsafe. (Does an 'iterate'
statement also skip the 'next' clause in for loops? Overall, it sounds like
a good way to start an I/O hang or a fork bomb.)
My main problem with relative-level breaks is the maintenance headache that
would ensue. Breaking out of N levels makes it much harder to analyze the
looping behavior for nested loops or when adding a new layer of nesting.
C++ maintenance is hard enough already; try hunting down which overloaded
operator gets called in a given context, especially when namespaces are
involved. At least with 'labeled' breaks/continues it's easier to spot
where the control transfers to. To make it really easy, you could even put
the label at the *end* of the loop. Oh... wait... that's exactly what goto
does now.
I don't think maintenance problems get enough attention in C++. It's still
a young enough language--one that's only slowly been accepted in many
places--that more programs are still in the 'building' phase than in the
'maintaining' phase. Spend some time reading other people's C++ in the late
integration or maintenance phases of a project, and you'll see what I mean.
The language solves a lot of C's scalability problems, but introduces
several of its own. In particular, I know why the Java people outlawed
operator overloading.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: dawks@best.com (phil dawkins)
Date: 1996/10/18 Raw View
sean@delta.com (Sean L. Palmer) wrote:
>> HOWEVER, having said all that, I agree that the goto SHOULD be removed,
>and
>> replaced with (a) structured equivalent(s). That is why I propose
>> essentially the naming of compound statements. The compound statement's
>> name can be used (including scoping rules) by breaks or continues.
[snip interesting "super" stuff]
>More than one 'super' modifier could be added. An alternative syntax which
>I actually think would be better is that break and continue (and iterate)
>could be followed by a constant positive integral count which determined
>how many levels of loops outward to apply it to, and defaulted to one (the
>current loop). So 'break 1;' would be equivalent to the current 'break;',
>and 'break 2;' would be equivalent to the 'super break' construct above.
Oh no, this would be extremely sad and a maintenance nightmare. In
assembler i would never write jmp $+15 rather than jmp label. At least
labels are symbolic whereas offsets and nesting levels are not. How
about turning it upside down and using labels for the goto statements
as well and using a "comefrom" as the target of the goto?
<code>
[label1:] goto target_label;
<code>
[label2:] goto target_label;
<code>
[comefrom:] target_label[:(label1,label2)];
This would document the process while still permitting regular
backward compatible gotos. With my lack of knowledge of compiler
technology this is probably fraught with major syntactic/semantic
difficulties, but it seems neat (at least imho), and far prettier than
templates although that's probably the wrong thing to say.
I use gotos for clarity. Exceptions are fine, but sometimes too much
hassle. Also, it's often not an exception but an expected and
anticipated condition. I just want to avoid the clutter from repeated
netsted "(workedOK && (condition))" type jobbies, when the obvious
solution is to bale (C++ is intended for use by us mortals, right?).
Good examples can be found in file io where the
exist/create/open/verify/read or exist/open/verify/read sequence is
often best served by a judicious isopened boolean and a transfer to a
point that closes the file only if it has been opened. Complex memory
management also works well with a boolean/goto pair. Other techniques
seem to lead to code clutter or complex conditions within which the
expected sequence is not applied (typical "never really tested 'cos we
could never make it happen" code).
phil.
--
The world is divided into two sorts of people: those that believe the
world is divided into two sorts of people, and those that don't.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/10/21 Raw View
Bradd W. Szonye wrote:
>
> My main problem with relative-level breaks is the maintenance headache that
> would ensue. Breaking out of N levels makes it much harder to analyze the
> looping behavior for nested loops or when adding a new layer of nesting.
> C++ maintenance is hard enough already; try hunting down which overloaded
> operator gets called in a given context, especially when namespaces are
> involved. At least with 'labeled' breaks/continues it's easier to spot
> where the control transfers to. To make it really easy, you could even put
> the label at the *end* of the loop. Oh... wait... that's exactly what goto
> does now.
>
Yep. With labeled 'break's you have to find the block label and then
find the end of that block in order to understand the resulting control
flow. With labeled 'break's, there is no obvious marker at the target
point to warn you that control is ariving from some oddball point in
the code. A good porgrammer will stick a big comment block at that
point, but there are too few good programmers around. At least with
a 'goto', the target label serves as a warning that something strange
is happening.
mtew@cds.duke.edu
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: comeau@panix.com (Greg Comeau)
Date: 1996/10/09 Raw View
In article <01bbb541$57db1d60$31d8cac6@chico> "Daniel Pflager" <dpflag@ix.netcom.com> writes:
>I don't know about you, but I've always hated that you can't break out of
>nested loops in C/C++ and transfer control where you actually want to go.
>
>e.g. This is what I want to do FUNCTIONALLY:....
>
>Or maybe what I want to do is associate some kind of name with each for
>loop like this:...
>
>BTW, I'm sure there are at least 1,000,000 work-arounds involving function
>calls, temporary variables, reorganizing, etc. I've probably used most of
>them.
>
>Maybe someone can suggest a better notation, but I guess you probably get
>what I'm driving at.
>
>Does anyone else think this would be a good idea?
This is available in other languages and enough people have
suggested it for C++ (and C). It will not make it into C++
(unless extensions by vendors) though you may want to consider proposing
it to C9X (but they've seen it too, so I doubt it'll fly there either).
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Here:comeau@csanta.attmail.com / BIX:comeau or comeau@bix.com / CIS:72331,3421
Voice:718-945-0009 / Fax:718-441-2310 / Prodigy: tshp50a / WELL: comeau
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/10 Raw View
comeau@panix.com (Greg Comeau) writes:
> In article <01bbb541$57db1d60$31d8cac6@chico> "Daniel Pflager" <dpflag@ix.netcom.com> writes:
> >I don't know about you, but I've always hated that you can't break out of
> >nested loops in C/C++ and transfer control where you actually want to go.
> >
> >e.g. This is what I want to do FUNCTIONALLY:....
> >
> >Or maybe what I want to do is associate some kind of name with each for
> >loop like this:...
> >
> >BTW, I'm sure there are at least 1,000,000 work-arounds involving function
> >calls, temporary variables, reorganizing, etc. I've probably used most of
> >them.
> >
> >Maybe someone can suggest a better notation, but I guess you probably get
> >what I'm driving at.
> >
> >Does anyone else think this would be a good idea?
>
> This is available in other languages and enough people have
> suggested it for C++ (and C). It will not make it into C++
> (unless extensions by vendors) though you may want to consider proposing
> it to C9X (but they've seen it too, so I doubt it'll fly there either).
I think that the major argument against it (within the standardization
committee) is that C/C++ already have a labeled break statement. It is
spelled "goto".
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Bjorn Fahller <ebcbear@ebc.ericsson.se>
Date: 1996/10/10 Raw View
J. Kanze wrote:
>
> I think that the major argument against it (within the standardization
> committee) is that C/C++ already have a labeled break statement. It is
> spelled "goto".
While a named break is indeed a goto, a goto is by no means a named
break. As a rule of thumb, I think the use of goto is a very good
sign of something being very wrong in the source code. I cannot see
anything such about a named break.
If possible (and I know it isn't,) I'd very much like to see goto
removed from C++ (and any other language too, for that matter,)
once and for all, and have it replaced by something more structured
that fills the one use of goto I can see that is not a sign of poor
coding.
_
/Bjorn.
--
Bjorn Fahller Tel: +46 8 4220898 /
NA/EBC/FNM/T -------------------
Ericsson Business Networks AB / A polar bear is a rectangular
S-131 89 Stockholm/SWEDEN / bear after a coordinate transform
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/11 Raw View
> If possible (and I know it isn't,) I'd very much like to see goto
> removed from C++ (and any other language too, for that matter,)
> once and for all, and have it replaced by something more structured
> that fills the one use of goto I can see that is not a sign of poor
> coding.
I am convinced of at least three good reasons to use gotos for effiency.
I) When shared code in an else clause (or implied else clause) would have
to be repeated with cascading nested ifs to achieve the same result.
II) When error handling code at the end of a procedure needs to be shared
(essentially a special case of I).
III) Recoding without a goto would introduce "state variables" (flags), or
cause the use of micro-functions whose only purpose is to avoid the goto.
HOWEVER, having said all that, I agree that the goto SHOULD be removed, and
replaced with (a) structured equivalent(s). That is why I propose
essentially the naming of compound statements. The compound statement's
name can be used (including scoping rules) by breaks or continues.
The example I gave used the goto syntax, but any suitable syntax could be
used.
Perhaps then, the question is not whether, but how?
What do you say?
Daniel Pflager
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/10/11 Raw View
"Daniel Pflager" <dpflag@ix.netcom.com> writes:
>I don't know about you, but I've always hated that you can't break out of
>nested loops in C/C++ and transfer control where you actually want to go.
Sure you can. You can use exceptions to break out of nested loops, so
there's no need for a language extension.
>e.g. This is what I want to do FUNCTIONALLY:
>
> for (some expressions) { // label1
> for (some other expressions) { // label2
> some code..
>
> if (something happens)
> break; // drops to line following "} // label1" below
>
> if (something amazing happens)
> goto done; // transfers to "done:"
>
> some more code...
> } // label1
>
> code code code...
> } // label2
>
> done:
> more code here...
Write this:
try {
for (some expressions) {
for (some other expressions) {
some code...
if (something happens)
break;
if (something amazing happens)
throw 0;
}
}
}
}
catch (...) {}
more code here...
Here I'm throwing an integer, but the type doesn't matter. The advantage
over your labeled break scheme is that cleanups automatically occur:
if objects with constructors are declared inside any of the loops,
their destructors will be called when you jump out of the loops.
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Work for something because it is good,
not just because it stands a chance to succeed. -- Vaclav Havel
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: ao@infinet.com (Mike Harrold)
Date: 1996/10/13 Raw View
Bjorn Fahller (ebcbear@ebc.ericsson.se) wrote:
: J. Kanze wrote:
: >
: > I think that the major argument against it (within the standardization
: > committee) is that C/C++ already have a labeled break statement. It is
: > spelled "goto".
: While a named break is indeed a goto, a goto is by no means a named
: break. As a rule of thumb, I think the use of goto is a very good
: sign of something being very wrong in the source code. I cannot see
: anything such about a named break.
No, no, no and no again. Someone has obviously been reading too many books
about "structured programming" written in the 1980s. Using a goto does
*not* signify something is 'very wrong in the source code'!
: If possible (and I know it isn't,) I'd very much like to see goto
: removed from C++ (and any other language too, for that matter,)
: once and for all, and have it replaced by something more structured
: that fills the one use of goto I can see that is not a sign of poor
: coding.
Why? They serve a very important purpose; or would you rather have the
language cluttered with even more useless keywords? Think about it,
a 'break' within a switch is essentially a goto. Break may look more
elegant but it is merely a short cut for a goto. Sure, you can add
test conditions, etc, etc, etc, to avoid using a goto, but if you are
writing optimised code, sometimes the use of a goto is just unavoidable.
The gentleman (I forget his name *blush*) who first called goto's evil,
also said they served a purpose. As long as they are used for that and
only that purpose, they are a perfectly acceptable method. The orginal
poster specified the classic example of where a goto is needed.
/Mike
--
+--------------------------------------------------------------------------+
| Take the cheese to sickbay, the Doctor should take a look at it as soon |
| as possible. -- B'lanna Torres - Star Trek Voyager - 'Learning Curve'. |
+--------------------------------------------------------------------------+
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jpotter@falcon.lhup.edu (John E. Potter)
Date: 1996/10/13 Raw View
Daniel Pflager (dpflag@ix.netcom.com) wrote:
: Does anyone else think this would be a good idea?
For my $.02, I would be just as happy if break and continue were removed
from the language, a case label forced a break, and return were only
allowed at the end of a function. I have not written code like what
you suggest since the 60's. How about a labeled altered goto?
A goto by any other name would stink as much. Spagetti code within a
class is a bowl of spagetti.
Yeah, leave them in the language for occasional use, but lets not try to
encourage abuse.
John
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Drinie@xs4all.nl (Rinie Kervel)
Date: 1996/10/14 Raw View
In <53o50l$e7e@news1.infinet.com>, ao@infinet.com (Mike Harrold) writes:
>: While a named break is indeed a goto, a goto is by no means a named
>: break. As a rule of thumb, I think the use of goto is a very good
>: sign of something being very wrong in the source code. I cannot see
>: anything such about a named break.
>
>No, no, no and no again. Someone has obviously been reading too many books
>about "structured programming" written in the 1980s. Using a goto does
>*not* signify something is 'very wrong in the source code'!
Well I, for one, stop reading a listing on the first goto encountered,
concluding that the author has not bothered to write structured code.
(He didn't made it good, before he made it faster).
I used to modify sources, to show that the goto's are easily removed,
but I just get bored with unstructured programs. In BSD TCP/IP sources for
instance goto's are used in command line argument passing, hardly the 10% part of the
program that is worth optimising.
>The gentleman (I forget his name *blush*) who first called goto's evil,
>also said they served a purpose. As long as they are used for that and
>only that purpose, they are a perfectly acceptable method.
That man, Dijkstra, stated that the purpose in a structured program should
be to leave a loop (break) or skip the rest of that loop (continue). The
harmfull aspect of a goto is that it can go anywhere. If you see a break,
you know it exits the loop you are in, if you see a goto you have to look
for the label. (The standard has to restrict gotos in C++ with regard to
jumping past constructors/destructors, that is violating the block structure of
the program)
Although I don't see why nested loops can't be place in functions and
use return for its exit (The cost of the function call may be neglected,
for the running time of the nested loops), I would suggest to place
the label in front of the loop as it is a property of the loop:
{
TopLevelLoop: for (...) {
...
for () {
...
if () {
...
break TopLevelLoop;
}
}
}
}
Rinie
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/14 Raw View
> : If possible (and I know it isn't,) I'd very much like to see goto
> : removed from C++ (and any other language too, for that matter,)
> : once and for all, and have it replaced by something more structured
> : that fills the one use of goto I can see that is not a sign of poor
> : coding.
> Why? They serve a very important purpose; or would you rather have the
> language cluttered with even more useless keywords? Think about it,
> a 'break' within a switch is essentially a goto. Break may look more
> elegant but it is merely a short cut for a goto. Sure, you can add
> test conditions, etc, etc, etc, to avoid using a goto, but if you are
> writing optimised code, sometimes the use of a goto is just unavoidable.
Agreed. 10 years ago (after about 10 years of programming experience) I'd
have agreed with the first writer. After 10 MORE years of programming
experience, I'm back where I was originally - advocating limited use of
gotos given no more suitable construct.
>
> The gentleman (I forget his name *blush*) who first called goto's evil,
> also said they served a purpose. As long as they are used for that and
> only that purpose, they are a perfectly acceptable method. The orginal
> poster specified the classic example of where a goto is needed.
Another individual recently posted the code rewritten using exceptions,
which actually handled the problem very nicely, and also handles the
examples I posted for "good" uses of goto, BUT
1) I'm thinking exceptions INSTEAD of break/continue/goto may result in
messy and confusing code too. After all, if they're being used for ought
than exceptions, are they no longer exceptions, but rules?
2) There are still a few C++s out there that don't support them.
3) Remembering my Fortran, Cobol and PL/I days almost 20 years ago now when
gotos were just falling out of favor, I recall that the worse examples of
spaghetti code I ran into were not spaghetti BECAUSE of the goto's, they
were spaghetti because of the misuse of state and pseudo-state variables
controlling which gotos were called. In fact, as I recall, the worse
example had LESS goto's. I remember reading the comments in this particular
example, where the author had been instructed by his project lead to use
less gotos. So he restructured the code so that there were more state
variables introduced, resulting in more complex conditionals controlling
less gotos. The thing had about 100 states controlled by about 10 different
variables (most of which were COMMON, the equivalent of global static
C/C++).
It was really hideous.
The point is, the gotos were not the problem, the variables were not the
problem - his thinking was the problem.
He was just hacking together the code as thoughts on what it should do
occurred to him, throwing in more and more special cases to be handled by
more and more state variables. He was avoiding the letter of his project
lead's advice by using less gotos.
Maybe he should have used more.
Exceptions may be the best answer, but I personally have not used them
enough to make an educated judgement.
Maybe in another 10 years...
Daniel Pflager
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: bradds@concentric.net (Bradd W. Szonye)
Date: 1996/10/14 Raw View
Mike Harrold <ao@infinet.com> wrote in article
<53o50l$e7e@news1.infinet.com>...
> Bjorn Fahller (ebcbear@ebc.ericsson.se) wrote:
> : While a named break is indeed a goto, a goto is by no means a named
> : break. As a rule of thumb, I think the use of goto is a very good
> : sign of something being very wrong in the source code. I cannot see
> : anything such about a named break.
>
> No, no, no and no again. Someone has obviously been reading too many
books
> about "structured programming" written in the 1980s. Using a goto does
> *not* signify something is 'very wrong in the source code'!
The way I see it, there are two ways of looking at things like multiple
returns, ifs, gotos, breaks, loops, and continues. You can say that if and
goto are the fundamental branch and jump instructions and that loops,
breaks, and continues are merely semantic sugar to make them easier to
write. Another way is that ifs, loops, breaks, and continues are the
fundamental branch and iteration instructions, and that gotos and multiple
returns are merely implementations of that technique. Some people would
like to remove that 'implementation' technique from the higher-level
languages and hide them in the generated code. Teaching languages like
Pascal take the latter approach, systems languages like C the former, and
most languages are somewhere in the middle.
> : If possible (and I know it isn't,) I'd very much like to see goto
> : removed from C++ (and any other language too, for that matter,)
> : once and for all, and have it replaced by something more structured
> : that fills the one use of goto I can see that is not a sign of poor
> : coding.
>
> Why? They serve a very important purpose; or would you rather have the
> language cluttered with even more useless keywords? Think about it,
> a 'break' within a switch is essentially a goto. Break may look more
> elegant but it is merely a short cut for a goto. Sure, you can add
> test conditions, etc, etc, etc, to avoid using a goto, but if you are
> writing optimised code, sometimes the use of a goto is just unavoidable.
It's not even a matter of optimization; it's a matter of style.
I sometimes like to write poetry. In fact, my favorite sort of poem to
write is an Elizabethan sonnet. Done properly, such a sonnet needs four
quatrains and a couple, in perfect iambic pentameter, with rhyme scheme
ababcdcdefefgg, no rhymes repeated, all rhymes perfect, each quatrain a
different extended metaphor building toward the couplet which summarizes or
'punch-lines' the sonnet.
That's an extremely rigorous form, and extremely challanging and *fun* to
write! I take the same approach to programming. Some programs are 'free
verse' using the entire crazy and sloppy range of the English (or other)
language; some programs are very precise and carefully structured both
syntactically and semantically.
X3J16 is in the same position as Daniel Webster: he wanted to standardize
(standardise?) American English spelling and meaning of words at a time
when such things were chaotic, before they got more chaotic. It wasn't his
job to remove 'bad' words from the language; merely to standardize prior
art. In some cases, he may have intentionally or accidentally introduced
new usage into the language. But it was not his job to ensure that the only
poems you could write were perfect sonnets. In the same way, the committee
cannot try to make sure that we can write only perfect programs.
You can't goto the middle of certain verses any more, but you can still use
a rough stretch of rhyme and meter to get the overall flow of the program
to work. Please excuse the horrible mixed metaphor. I personally take the
sonnet approach to programming; I restrict the parts of the language I use,
falling back to cheap hacks only when time is tight, the program doesn't
matter, or I can't figure out the right way to do it yet. It's still an
internal embarassment (to me if no-one else) when I can't write a 'perfect
sonnet' in code however.
> The gentleman (I forget his name *blush*) who first called goto's evil,
> also said they served a purpose. As long as they are used for that and
> only that purpose, they are a perfectly acceptable method. The orginal
> poster specified the classic example of where a goto is needed.
There's some debate about how exactly Edsgar Dijkstra felt about gotos at
the time of the "Considered Harmful" paper. Some think he added the 'goto
is occasionally useful, when used properly' part either because of
practical limitations of then-popular languages or as a simple hedge to
deter 'flames'--riding both sides of the fence.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Larry J Evans <evansl@cs.tamu.edu>
Date: 1996/10/14 Raw View
Daniel Pflager wrote:
>
> > If possible (and I know it isn't,) I'd very much like to see goto
> > removed from C++ (and any other language too, for that matter,)
> > once and for all, and have it replaced by something more structured
> > that fills the one use of goto I can see that is not a sign of poor
> > coding.
>
> I am convinced of at least three good reasons to use gotos for effiency.
>
> I) When shared code in an else clause (or implied else clause) would have
> to be repeated with cascading nested ifs to achieve the same result.
>
> II) When error handling code at the end of a procedure needs to be shared
> (essentially a special case of I).
>
> III) Recoding without a goto would introduce "state variables" (flags), or
> cause the use of micro-functions whose only purpose is to avoid the goto.
>
Why not the following:
break label
continue label
goto label
where the label in 'goto label' would have to be lexically after the
goto
statement.
According to B.S. Baker's "An Algorithm for Structuring Flowgraphs"
_JACM_24(1),
1977, any "reducible" program with goto's can be restructure WITHOUT
copying.
The above article describes a "reducible" program as one where any loop
can be
entered in only one place(p.101). It also describes a workaround for
non-reducible
programs(p.108). Although not explicitly stated in the article, I
believe the
workaround would have to involve some "state variable" to indicate
whether the loop
had already been entered.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/15 Raw View
> Why not the following:
>
> break label
> continue label
> goto label
>
> where the label in 'goto label' would have to be lexically after the
> goto
> statement.
This is good. I like this.
>
> According to B.S. Baker's "An Algorithm for Structuring Flowgraphs"
> _JACM_24(1),
>...
> workaround would have to involve some "state variable" to indicate
> whether the loop
> had already been entered.
Any chance you can post the full citation?
You wouldn't happen to know the famous Djistra goto citation as well would
you? I think it might be useful to explore these a bit.
What do you think?
Salut,
Daniel
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/15 Raw View
> That's an extremely rigorous form, and extremely challanging and *fun* to
> write! I take the same approach to programming. Some programs are 'free
> verse' using the entire crazy and sloppy range of the English (or other)
> language; some programs are very precise and carefully structured both
> syntactically and semantically.
I like your analogy friend. I agree, although I'm more of a George Orwell
kind of programmer - use simple words - use them clearly - get done in time
for dinner.
> sonnet approach to programming; I restrict the parts of the language I
use,
> falling back to cheap hacks only when time is tight, the program doesn't
> matter, or I can't figure out the right way to do it yet. It's still an
> internal embarassment (to me if no-one else) when I can't write a
'perfect
> sonnet' in code however.
I'm too old to be embarrased by any code I write. Nor do I consider any use
of tools a cheap hack, unless it does not communicate its purpose or
intention with clarity. Finally, in my experience, time to do it "right" is
rare.
I have run into many people who love the pure philosophy of programming.
What is the "right" way to do things, etc. Such people love the pure
mathematics of programming.
I'm more of an engineer than a mathematician. My motto is "It doesn't have
to be perfect - just good enough".
Having said that, I've run into enough misuse of gotos (including my own)
to want a better alternative. Break and continue don't provide a complete
solution, however, and that's what I'm looking for.
Best idea so far involved using exceptions to handle the case that I
mentioned. What I wonder is - are there any others?
Daniel Pflager
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Max TenEyck Woodbury <mtew@cds.duke.edu>
Date: 1996/10/16 Raw View
Greg Comeau wrote:
>
> In article <01bbb541$57db1d60$31d8cac6@chico> "Daniel Pflager"
> <dpflag@ix.netcom.com> writes:
> >I don't know about you, but I've always hated that you can't break out of
> >nested loops in C/C++ and transfer control where you actually want to go.
> >
> >e.g. This is what I want to do FUNCTIONALLY:....
> >
> >Or maybe what I want to do is associate some kind of name with each for
> >loop like this:...
> >
> >BTW, I'm sure there are at least 1,000,000 work-arounds involving function
> >calls, temporary variables, reorganizing, etc. I've probably used most of
> >them.
> >
> >Maybe someone can suggest a better notation, but I guess you probably get
> >what I'm driving at.
> >
> >Does anyone else think this would be a good idea?
>
> This is available in other languages and enough people have
> suggested it for C++ (and C). It will not make it into C++
> (unless extensions by vendors) though you may want to consider proposing
> it to C9X (but they've seen it too, so I doubt it'll fly there either).
>
BLISS is a completely structured language. It has named 'break's and no
'goto'. It is (or was) the standard implementation language for a certain
large computer company, and I read a lot of BLISS code when I worked for
them. From experience, named 'break's are A LOT WORSE to deal with than
'goto's. Counted 'break's, like this proposal, are a little easier to
read and understand when the count is small, but 'break's out of more than
three (probably more than two) levels might even be worse than named
'break's, and their potential hazard to anyone who has to change code
containing them is obvious.
While 'goto's should be used sparingly, they do serve a useful function.
Properly used, they can make a program MORE readable. (People who turn
up their noses at code with 'goto's in it are saying more about them-
selves than they are saying about the code.) 'Goto's can be overused,
and their overuse usually results in hard to follow code, but the
elimination of 'goto's does NOT assure easy to follow code.
mtew@cds.duke.edu
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Sam Fenster <fenster@cs.columbia.edu>
Date: 1996/10/16 Raw View
jbuck@Synopsys.COM (Joe Buck) writes:
> Here I'm throwing an integer, but the type doesn't matter. The advantage
> over your labeled break scheme is that cleanups automatically occur: if
> objects with constructors are declared inside any of the loops, their
> destructors will be called when you jump out of the loops.
Are you saying that a `break' or `goto' out of a loop won't call the
destructors of that block's local variables?
April WP:
| 6.6 Jump statements [stmt.jump]
|
| 1 Jump statements unconditionally transfer control.
| jump-statement:
| break ;
| continue ;
| return expressionopt ;
| goto identifier ;
|
| 2 On exit from a scope (however accomplished), destructors
| (_class.dtor_) are called for all constructed objects with automatic
| storage duration (_basic.stc.auto_) (named objects or temporaries)
| that are declared in that scope, in the reverse order of their decla-
| ration. Transfer out of a loop, out of a block, or back past an ini-
| tialized variable with automatic storage duration involves the
| destruction of variables with automatic storage duration that are in
| scope at the point transferred from but not at the point transferred
| to. (See _stmt.dcl_ for transfers into blocks).
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Daniel Pflager" <dpflag@ix.netcom.com>
Date: 1996/10/08 Raw View
Hi,
I don't know about you, but I've always hated that you can't break out of
nested loops in C/C++ and transfer control where you actually want to go.
e.g. This is what I want to do FUNCTIONALLY:
for (some expressions) { // label1
for (some other expressions) { // label2
some code..
if (something happens)
break; // drops to line following "} // label1" below
if (something amazing happens)
goto done; // transfers to "done:"
some more code...
} // label1
code code code...
} // label2
done:
more code here...
What I'd rather do is something (equivalent) like:
for (some expressions) { // label1
for (some other expressions) { // label2
some code...
if (something happens)
break; // equivalent to break 1;
if (something amazing happens)
break 2; // meaning break two times
some more code...
} // label1
code code code...
} // label2
Or maybe what I want to do is associate some kind of name with each for
loop like this:
for (some expressions) label1: {
for (some other expressions) label2: {
some code...
if (something happens)
break;
if (something amazing happens)
break label1; // meaning break relative to label1
some more code...
} // label1
code code code...
} // label2
BTW, I'm sure there are at least 1,000,000 work-arounds involving function
calls, temporary variables, reorganizing, etc. I've probably used most of
them.
Maybe someone can suggest a better notation, but I guess you probably get
what I'm driving at.
Does anyone else think this would be a good idea?
Daniel Pflager
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]