Are gotos truly evil?

  • Thread starter Thread starter Guest
  • Start date Start date
I rather do

try
{
for (...)
{
for (...)
{
...
DoStuff () ;
if (discontinue) throw new MyException (...) ;
}
}
}
catch (MyException e) {}
....

kind of structured gotos.

/LM
 
Using Exception instead of goto?
Even worse!

Luc E. Mistiaen said:
I rather do

try
{
for (...)
{
for (...)
{
...
DoStuff () ;
if (discontinue) throw new MyException (...) ;
}
}
}
catch (MyException e) {}
...

kind of structured gotos.

/LM
 
HC said:
Which is cleaner?

When looping on a condition, you should use a "while" loop instead of a
"for" loop.

Also, nesting 4 loops deep should be avoided if at all possible.
 
Michael A. Covington said:
Much closer to home, here's what Steve McConnell (of "Code Complete")
says:
http://www.stevemcconnell.com/ccgoto.htm

Basically an extended demonstration that 'goto' has its legitimate uses.

In particular, he shows you some algorithms where "Use no gotos" conflicts
directly with the principle "Only express each idea once". Duplicate code
is bad because your two expressions of the same idea may not be identical,
especially if, later on, you have to maintain the code; you may not
succeed in keeping them in sync.

Being a fan of McConnell, I made a careful read of the page you pointed me
to. It is interesting that the path that he chose to illustrate his "no go
to" debate from was one that illustrates how to REWRITE code from "including
goto" to "excluding goto." I have a problem with this characterization.

The cognitive exercise places into the mind an understanding of the
algorithm from the viewpoint of a procedure written with goto in mind, and
then attempts to show that the algorithm is less readable or potentially
more prone to problems if you rewrite it. This shows only that if you
present an idea, in one form, and ask your reader to go through a mental
exercise to understand it, that it may be hard for that same reader to
immediately follow the exercise with one in which s/he has to relearn the
algorithm from another point of view. I'm not completely convinced that the
mental process that the reader goes through in this example is a valid
process for comparison, because it is a "code-only" process and does not
factor in design time considerations.

In other words, what Steve did NOT do is illustrate how valid OO thinking
would have led away from this situation in the first place. The author of
the code is much more likely not to have written code filled with "goto"
statements and this triggering this rewrite and the ensuing comparison,
because a person who described applications in terms of their patterns would
not have lept to the conclusion that an implementation that uses goto makes
much sense.

As a coding leader, it is my responsibility to encourage this kind of
thinking, because the benefits it reaps across the project are immense. If
a programmer in using 'goto', even in a rational and constrained way, I
would be led to wonder if he was thinking about the problem in terms of
patterns, since there are no OO patterns that use the goto.

In fact, the specific example that you cite is nearly perfect for
demonstrating the effective use of the strategy pattern, where parts of an
algorithm are seperated from, and replacable by, other parts. This, in
effect, creates a system whereby control structures within an algorithm can
be seperated from calculation logic and expressed independently.

It is also interesting to note that this article, like the rest, makes the
comparison between structured programming with the 'goto' and structured
programming without the 'goto.' No article makes the comparison with OOP in
the mix. Perhaps this is because no more recent study on the debate,
including in the OO world, has found anything new to say. Or, perhaps, no
one cares as much any more.

I'm afraid that we will not agree on this point. However, I appreciate the
discussion.
--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
Your position is basically "Thou shalt not think of certain algorithms,"
then, right?

Can you demonstrate that these algorithms are undesirable?
 
Michael A. Covington said:
Your position is basically "Thou shalt not think of certain algorithms,"
then, right?

Can you demonstrate that these algorithms are undesirable?

The definition of an algorithm (loosely) is a specific set of steps used to
solve a known problem.

Let's work backwards from that.

Algorithms solve problems. There is the problem first. The design attempts
to solve the problem. During implementation, the developer may select an
algorithm as the basis for his coding.

On that basis, I maintain that there is NO problem that cannot be solved
without the use of a goto. It is quite possible that there is an algorithm
that specifies GOTO as one of its steps, and a case could be made that to
convert that step to another that is functionally equivalent is to implement
a different algorithm, because the definition of algorithm includes the word
'specific.'

Therefore, I am sidestepping a little. I am stating (from a position of
weakness and admittedly less learning than you, which is dangerous) that you
cannot present to me an algorithm that solves a problem where I cannot craft
a functionally equivalent bit of OO code to solve the same problem without
the use of a goto. In that aspect, I will say that I am not turning away
from ANY problem... only implementations that are not worth maintaining
because the coding of them teaches bad habits.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
There's another issue too, which is code generation. On the one hand I
could say that I've not written a goto in C# or C++, but the truth is
that I've used lex/yacc/antlr and those tools have generated goto
statements.

Now this isn't code that's meant to be human readable. The goto
statements don't show up in the source tree and aren't reviewed in
code review. But parser generators are a lot more elegant to write if
the destination language has a goto or equivalent.

While I have used Lex and YACC, I cannot make any claim to have written a
_system_ to generate code that deterministically parses a language. (It
would be an interesting exercise, but alas, that work belongs to another
team at Microsoft :-). Therefore, I have no grounds to either agree or
disagree with your statement.

I will say that I see no reason, other than the fact that the developers of
those languages had already written parser code using goto, that they would
be _required_ to generate code that used a goto. I can easily _concieve_ of
designs that would generate code that does not use a goto.

That said, you are correct in your assertion that this type of code is not
designed to be human readable and would normally be excluded from human code
review (except for instances of white-box testing). In that sense, it is
object code. For this sake, I feel that it may be fair to let a 'generated'
goto statement remain in a production codebase, as long as the tool that
generates the code, and the source data that it used, is maintained along
with the code itself.

--
--- Nick Malik [Microsoft]
MCSD, CFPS, Certified Scrummaster
http://blogs.msdn.com/nickmalik

Disclaimer: Opinions expressed in this forum are my own, and not
representative of my employer.
I do not answer questions on behalf of my employer. I'm just a
programmer helping programmers.
--
 
On that basis, I maintain that there is NO problem that cannot be solved
without the use of a goto.

That is correct and can be proved mathematically (assuming you have
for-loops, while-loops, if-then-else structures, and the usual structured
programming stuff).

However, the cost is that in some circumstances you must code the same test
in more than one place. This is not common in C-like languages, especially
because in C, you have 'break' and 'continue', which are not part of the
minimum set of structured programming constructs; they are essentially
restricted 'goto' statements. Real purists would object to 'break' and
'continue.'
Therefore, I am sidestepping a little. I am stating (from a position of
weakness and admittedly less learning than you, which is dangerous) that
you cannot present to me an algorithm that solves a problem where I cannot
craft a functionally equivalent bit of OO code to solve the same problem
without the use of a goto.

I don't dispute that at all. Using 'goto' raises the risk of programmer's
error. Coding the same test in more than one place also raises the risk of
programmer's error. It's a trade-off. I reject the claim that 'goto'
should always be avoided at any cost. There is a cost.

Pointers, as I noted before, *really* raise the risk of programmer's error;
they do to memory what 'goto' does to code execution. That's why I'm glad
C# minimizes use of them. I find C an annoyng language because the flow of
control is so structured but the use of memory is so error-prone.

Also, I don't advocate *common* use of 'goto'. I code about one per year.
If I were programming full-time, I'd probably code one every three months.
They always have very limited scope (i.e., they jump very short distances).

You could probably eliminate all of them by inventing another kind of
restricted 'goto' along the lines of 'break' and 'continue'.
 
Certainly, one of the best reasons to have 'goto' in a language is
machine-generated code.

There is a lot of compiler technology that assumes 'goto' is present (which
it always is, in machine language).

Maybe you want to take a compiler, or the logic of a compiler, and have it
output C# rather than MSIL, for language translation purposes. Having it
use 'goto' would not introduce errors.
 
You could probably eliminate all of them by inventing another kind of
restricted 'goto' along the lines of 'break' and 'continue'.

Something along the lines of Java's labelled break/continue?

For example:

public class Test
{
public static void main(String[] args)
{
OuterLoop:
for (int i=0; i < 5; i++)
{
for (int j=0; j < 4; j++)
{
if (i*j > 10)
{
break OuterLoop;
}
System.out.println (i+" "+j);
}
}
}
}

I very occasionally wish C# had this functionality. (There are other
bits of Java I'd want first though - the enums introduced in 1.5 would
probably be top of the list...)
 
Something along the lines of Java's labelled break/continue?

For example:

public class Test
{
public static void main(String[] args)
{
OuterLoop:
for (int i=0; i < 5; i++)
{
for (int j=0; j < 4; j++)
{
if (i*j > 10)
{
break OuterLoop;
}
System.out.println (i+" "+j);
}
}
}
}

Sorry if this sounds harsh, but this is why I *hate* contrived examples. No
one would *ever* write code like that because the code does nothing. But I
digress.....

The problem with your example is that you used "for" loops when you should
have used "while" loops. When looping on a condition, use "while". When
looping a set number of times, use "for". Any time you stick "break" into a
"for" loop you know you've used the wrong type of loop.

The problem is, the "for" loop in C# is so darn convenient. I find myself
doing the same thing you just did. When searching through a list I use a
"for" loop and "break" out when I find my item. Why? Less typing I suppose.
But even though I'm guilty of doing it I still think it's simply lazy
coding. :-)
 
Sorry if this sounds harsh, but this is why I *hate* contrived examples. No
one would *ever* write code like that because the code does nothing. But I
digress.....

It wasn't meant to be an example of where it would be handy - it was
*only* meant to be an example of the syntax.
The problem with your example is that you used "for" loops when you should
have used "while" loops. When looping on a condition, use "while". When
looping a set number of times, use "for". Any time you stick "break" into a
"for" loop you know you've used the wrong type of loop.

Do you hold that to be true with foreach as well?
The problem is, the "for" loop in C# is so darn convenient. I find myself
doing the same thing you just did. When searching through a list I use a
"for" loop and "break" out when I find my item. Why? Less typing I suppose.
But even though I'm guilty of doing it I still think it's simply lazy
coding. :-)

I'm not sure - I think the "for" loop shows the "going through a list"
bit more readably than the while loop would. The while loop, however,
expresses the "while I haven't found what I'm looking for" bit more
readably.
 
Do you hold that to be true with foreach as well?

Doesn't the term "for each" imply that you are going to process "each" item
in the list? Doesn't "break" prevent that from happening?

I know it's very strict, and as I said I don't always follow it in practice
either, but from a idealogical perspective it doesn't make sense to me to
use "continue" or "break".
 
Scott Roberts said:
Doesn't the term "for each" imply that you are going to process "each" item
in the list?

Not to me. To me, it means the loop itself just goes through each
element, if left to its own devices (as it were).
Doesn't "break" prevent that from happening?

It certainly does.
I know it's very strict, and as I said I don't always follow it in practice
either, but from a idealogical perspective it doesn't make sense to me to
use "continue" or "break".

To me, using a foreach loop and breaking once you've found something is
much more readable than using a while loop. When ideology gets in the
way of readability, it's time to modify the ideology IMO :)
 
Jon Skeet said:
Not to me. To me, it means the loop itself just goes through each
element, if left to its own devices (as it were).

Yes, unless the programmer decides to "goto" somewhere else at some point
within the loop. :-)
To me, using a foreach loop and breaking once you've found something is
much more readable than using a while loop.

Yeah, but now we're talking about implementing linear search algorithms.
That makes me cringe too! :-)
When ideology gets in the
way of readability, it's time to modify the ideology IMO :)

Can't argue with that. The reality is that "break", "continue", and "goto"
do not make code *inherently* bad or unreadable. However, I would say that
heavy use of those constructs probably indicates one is heading down that
road.
 
Scott Roberts said:
Yes, unless the programmer decides to "goto" somewhere else at some point
within the loop. :-)
Indeed.


Yeah, but now we're talking about implementing linear search algorithms.
That makes me cringe too! :-)

It shouldn't - not when that's the simplest thing to do, and there's no
chance of it being a bottleneck. (That's not always the case, of
course, but it often is.)
Can't argue with that. The reality is that "break", "continue", and "goto"
do not make code *inherently* bad or unreadable. However, I would say that
heavy use of those constructs probably indicates one is heading down that
road.

Sure.
 
I certainly don't think they are evil.
Yes they can be abused, but so can anything else.
Sometimes efecitve use of flow control schemtics, like switch,
break, and yes even goto can create cleaner code then nested if's, and
traditional OO programing.

The way I've used goto's most often is in creating functions with a single
exit point for tracing purposes. This was a c application, with .net I'd
use a try, catch, finally, which is in someways just an elegant goto
statement.
 
Hi :)

I would like to deffereniate between two goto's statement

goto in old days
and
goto in current days

I used to program BASIC at MSX
goto was an important statement for the language
because you don't have functions :)

and to simulate functions another statement was GOSUB

I think the dangerous of goto is disappeared in any procedural language

BASIC (and also Assembly) is not considered to be procedural language

means that goto statement could throw you in any code in your program.

but try to make anonymous function in C# 2.0 and make a goto statement that
is outer the boundary of it immediately the compiler will refuse to compile
:(

in my opinion the goto bad reputation was inroduced as an effect of the old
days programming
remember you were only coding in
- ONE FILE
- ONE piece of code ( which your enrty point was the first line of code and
the end was at the last )

I have a fortran program written by my proffessor to solve something about
thermodynamics stuff. I got astonished about the amount of the goto statement
in it, But suddenly I knew why he was using it. The calculations where
accumulated and he needs to make some sort of testing at every stage so he
was using goto to transfer the program to the end line.

I don't consider goto statement is an evil unless the numbering come
back to any language [ may be thats why labels inroduced in the procedural
language ]

in another way you CAN'T goto from CLASS A code to CLASS B code with out
instantiating the two classes and know a set of methods to call

its all about transferring the current control to another control

so goto nowdays is really really limited to the their block of code

I don't make a huge lines in one method
instead I make many many few methods which I suddenly discovered that it is
unreadable

so if you see goto statement in c# don't panic as it is not the no.1
source of complexitiy and I repeat it is only affecting its enclosed block
{} unless you are typing all of your program in the main() :)

goto is very romantic statement it makes you escape from your
responsibilities and it expresses our weakness as a human being if there is a
program without an ERROR then I might be wrong :)
 
Just spent best part of an hour reading this and the examples etc... to have
my thoughts already posted right there at the end...

Perhaps someone with a little more knowledge than me can explain the
differences between goto & try... catch... finally... within a c# context

Afterall, to not try catch is inherintely bad is it not - yet, as name sake
said, it seems to be an elegant Goto.

TerryC
 
First and foremost I agree with the posters that believe gotos are not worth
the trouble, can lead to confusing logic, are completely unnecessary and most
likely indicate bad design.

With that said, there is one thing that almost all programmers miss about
gotos; We all use them all of the time. I would actually go as far as to say
that each and every programmer uses gotos on a daily bases. All conditional
logic, including looping logic and the break and continue commands cannot
possibly work without an implicit goto statement.

The “if†statement can be interpreted as IF true DO expression1 GOTO
“immediately beyond expression 2 to continue with logic†ELSE DO expression 2
END IF continue with logic.

The “for, while, until†statements can be interpreted similarly.

And for the more explicit logic control but still considered implicit goto
statements the break and continue can be interpreted as follows;

- “break†- GOTO immediately beyond the conditional or looping logic in the
current scope
- “continue†- GOTO the next iteration of the looping logic in the current
scope

My opinion is that implicit gotos are fine if not necessary, the explicit
GOTO statement is both unnecessary and an indication of logic flow design.
 
Back
Top