Archived

This topic is now archived and is closed to further replies.

Voodoo4

The EVIL goto...

Recommended Posts

Voodoo4    122
On the web there are many resources on c and c++ and many good tutorials. In these tutorials you get good reference on c's basic statements like if,do-while,switch,etc. But when it comes to the goto statement everyone is treating it as the spawn of evil,the satan's child! This is also happening in books of serious authors and it is really sad. Everyone wants to make clear that "a good programmer should never use the goto!" . Well ok,i agree.You can write your code again without the use of goto,but since it exists why should you ignore it? Why then the compiler authors don't exclude it from their c version? The goto statement is very usefull when you have to deal with deep nested loops.Goto-Jumping may save you from lots of typing. Saying that goto should be eliminated i believe is narrow minded thinking.If there's something to eliminate that is unreasonable use of it. If you can avoid it then avoid it. I have never understood this "gotoless" programming frenzy really.They say it makes the code a mess. Well if you're not a neat programmer i think this isn't goto's fault! Voodoo4 Edited by - Voodoo4 on 7/23/00 1:16:13 PM Edited by - Voodoo4 on 7/23/00 1:16:57 PM

Share this post


Link to post
Share on other sites
ImmaGNUman    122
Its very simple, goto is evil.

-----------------------------

A wise man once said "A person with half a clue is more dangerous than a person with or without one."

Share this post


Link to post
Share on other sites
Arjan    122
I''ve never used goto before (but I haven''t coded much yet ) but I don''t look at it as an evil statement. Offcourse, (almost?) everything can be done without goto (and also with goto ). I''ve seen enough code using goto where it was the best way to use goto, so yes, goto has a good use. I will use it when I feel I need to use it.

-------------------------
-Programmers don't byte, they nibble a bit.
Unknown Person
-------------------------

Share this post


Link to post
Share on other sites
Dogfood    122

The reason goto was included is for those situations in which you absolutely have to have it, and since C is a systems programming language, there are instances when writing say an OS kernel in which goto has its uses.


goto is not evil in and of itself, but as a programmer who spent a few years(in 80''s) writing BASIC code, I will say that goto''s produce code which is unreadable after a certain size. Gosub(from BASIC) isn''t much better. Functions accomplish many of the same purposes, but encourage reuse and reduce causes for errors(like inadvertently changing a variable used by the code the goto''d the current code). if''s/ do''s/ while''s/ for''s/ function''s/ and switch''s will accomplish everything goto does but will make your life easier in 3 months when you come back to look at it. This is experience talking, not computer science, and just be glad you don''t have to use line numbers(one renum and you''re spending HOURS figuring out where sections of code are).

Share this post


Link to post
Share on other sites
egerlach    122
Well, in my experience I''ve only ever used goto once (ever since I stopped programming in BASIC on my TI-99-4A back when I was 7). It was during the ECOO team programming competition 2 years ago. It was with 3 minutes left in the competition that we realized a bug in our code. We needed an exit condition in the middle of our 15 nested for loops. Now, the only reason that 15 nested for loops even cropped up is because we were programming under a deadline, and a very tight one at that. The solution sucked, but it worked. So anyways, as opposed to coding in 15 extra conditions, we used Pascal''s goto statement. It got the job done.

My CS prof hit me when I told him.

Essentially, people are so opposed to goto because there really is no reason for it to be used. You can do anything you want with other constructs, particularily functions. If you have a bunch of nested loops or something, look for a cleaner way to cut out of them. You''ll love yourself later.

Share this post


Link to post
Share on other sites
mossmoss    326
The goto statement is not evil.

It has the potential to be abused much more than other statements; by inexperienced programmers and those who come from BASIC (or similar) backgrounds, goto does get abused.

But the occassional and proper use of goto can make code readable and easy to maintain over using other sorts of control structures.

However, I find the need to use goto is very infrequent. Also keep in mind that while every ANSI C conforming compiler supports it, not all support it well. Because of the bad rap it has gotten and the infrequency of its use, various compilers will either botch the generated code or optimize it poorly. That in itself may be a reason to avoid or minimize using goto .

---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
The_[PI]_ehT    122
quote:
Original post by mossmoss

...those who come from BASIC (or similar) backgrounds, goto does get abused.



yep, that''s the case. We don''t want to show that we started with *laaaaame* basic

pi~


btw what''s a blue programmer?

Share this post


Link to post
Share on other sites
LeeIsMe    122
It is my understanging that the use of goto can be bad in some situations due to undefined behavior. (goto into an if, for loop, or something else)
Because it can be bad and isn''t absolutely necessary to programming, most people thing it is a bad idea.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
"goto is EVIL!!!" they say. Has anybody noticed that exception handling (try/catch/throw statements)--and ''throw'' in particular--are really stylized goto statements? Stick a label where the catch() is, change ''throw'' to goto and it works exactly the same.

So next time someone tells you that goto is Evil(TM), ask them if they approve of exception handling. If they say yes, just sit back and smile.

Oh, and if that isn''t convincing enough, answer this: what is the one statement in C or any other language that compiles to a *SINGLE* instruction on just about every chip known to mankind? Call it JMP, BRA, or whatever, it''s still GOTO to me

--Capt. Mathew Neville

Share this post


Link to post
Share on other sites
TimSmith    122
Well, exception handling does a LOT more than goto, but point is well taken. =)

IMHO, goto is one of those tools that is more liable to do damage than good. New programmers should stay away from goto while they get experience. Then once you have a good understanding of real world programming, then goto can be used effectively.

I once was talking to someone who had a masters in music. He said that when getting your bachelors (sp?), you learn all the rules to making music. When getting your masters, you learn how to break those rules. I think of goto the same way, you must first learn the rules of structured programming before you can really understand when to use goto.

Tim

Share this post


Link to post
Share on other sites
Capt. Neville    122
I learned in the old old school of Basic programming. The way I learned was how to program structureless, THEN learn how to write structured programs in C. It depends on your preferred learning style. I dare say I write cleaner code now than most anybody else''s code I''ve seen--and more efficient code, as well. I rarely use goto, but when I need it, I use it.

To use another analogy, babies learn simple words and phrases before they learn the grammatical rules to form sentences. Then they learn the ''structure'' of the language. THEN they can learn how to break the rules to form what we call literary ''style''. You were right--you just left the first step out

I will agree that goto should be used sparingly. But it is not the Evil(TM) everyone says it is. I also come from a pitiful school known as the University of South Carolina, and trust me--99% of the people there have FAR worse coding problems than misusing goto

--Capt. Neville

Share this post


Link to post
Share on other sites
milo    122
quote:

By Voodoo4:
The goto statement is very usefull when you have to deal with deep nested loops.Goto-Jumping may save you from lots of typing.



And a car probably can run on three wheels which saves you time rotating the tires. Faster doesn''t make right. Quality before quantity.


quote:

By mossmoss:
by ... those who come from BASIC (or similar) backgrounds, goto does get abused.



Hey, I resemble that statement at it''s full of bull! I started with BASIC in 1980, before there was a C for the masses and before C++ even existed. I never abused GOTO''s in BASIC, though you are required to use them. I''ve never used a GOTO in C or C++, except break or continue in a loop - restricted GOTOs, IMHO. I also know the type of situation where you might use it, for speed, but I would think that except for rare situations on embedded systems that is probably not a worthy reason anymore. Of course, I learned BASIC self-taught from a book before ever touching a computer and my 2nd language was self-taught Assembler. Have to love the old Apple IIe. Schweet! To realy date me, I remember all the hub-bub when Apple IIe''s came out with 64K RAM. Now that was a God box!

Mike Roberts
aka milo
mlbobs@telocity.com

Share this post


Link to post
Share on other sites
Capt. Neville    122
quote:
Original post by milo
I also know the type of situation where you might use it, for speed, but I would think that except for rare situations on embedded systems that is probably not a worthy reason anymore.



Excuse me, but last time I checked, this is a GAME DEVELOPER site. As game developers, it''s our *responsibility* to write the fastest, most efficient code possible. The less efficient your code, the slower it goes, the less you can do in a game. It is our *job* to push the limits of hardware to produce ground-breaking and breathtaking games. The minute we fail to do that, we have failed the people we serve: the game players.

Just because we have 800Mhz chips now doesn''t mean we can become lazy--it just means we have to stretch ourselves even FURTHER. Use those cycles to do new and better things, not as an excuse to become lazy.

Not a "worthy" reason? Think again.

--Capt. Neville

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Goto''s can also cause the newer processors to mess up their branch prediction causing pipeline flushes. Besides that optimizing compilers can''t efficiently optimize code with goto''s in it for similar reasons

Share this post


Link to post
Share on other sites
Capt. Neville    122
Can''t, or won''t? Just because a compiler doesn''t optimize it doesn''t mean it can''t be done.

And yes, I''m aware of the Pentium''s pipeline flushing. A mistake, if you ask me. If anything, they''re *more* predictable than the conditional jumps, not less.

Anyway, you still haven''t addressed my point: if goto is so evil and unoptimizable, then how is throw any better? Or break or continue, for that matter?

Share this post


Link to post
Share on other sites
Dogfood    122

It is worthy of note that it is only necessary to support 1 type of conditional branch statement to create ALL other types of control structures. In fact, the assembly code for function calls and other flow control structures involve lots of "goto''s" and its conditional branching cousins(although the less the better in terms of optimization). So not only does Exception handling use it, but so does everything else.


However, the reason GOTO''s caused trouble in BASIC was because it was really about your only option for anything that couldn''t be handled by a for/next loop(which was less capable than the kind found in C). GOSUB''s were slightly better since they stored the return address and so could be called from anywhere in a program.


GOTO''s can dramatically obfuscate code, even if you have labels instead of line numbers. This doesn''t make them evil. And optimization wise, I imagine the branch prediction units work VERY well for straight jumps since there is no conditional to affect anything. Basically, GOTO''s can be a big source of obfuscated code, and the purpose of using a high level language is to help make the programmer''s job easier. And even if we are game programmers, writing whole games in assembly language may make them faster, but I assure that there are a great many games that would have remained unwritten were it not for high level languages and the greater expressiveness the variety of control structures they have allow.


Someone mentioned that as game programmers we are supposed to write the fastest, most efficient code possible, well, I''m not entirely sure that''s a true statement. When we are limited by hardware, we HAVE to write tight code because it won''t work otherwise, but as hardware becomes more capable, we can better exploit that capability not by making our RPG''s run at 300fps, but by enhancing AI, adding depth and details to interaction. The complexity of the code to do many of these things requires language features to support your complexity, not hand written assembly optimizations, and as complex as processors are getting, I would say that compilers do a better job optimizing than most assembly programmers I know.

Share this post


Link to post
Share on other sites
milo    122
quote:
Original post by Capt. Neville
Excuse me, but last time I checked, this is a GAME DEVELOPER site. As game developers, it''s our *responsibility* to write the fastest, most efficient code possible. The less efficient your code, the slower it goes, the less you can do in a game. It is our *job* to push the limits of hardware to produce ground-breaking and breathtaking games. The minute we fail to do that, we have failed the people we serve: the game players.

Just because we have 800Mhz chips now doesn''t mean we can become lazy--it just means we have to stretch ourselves even FURTHER. Use those cycles to do new and better things, not as an excuse to become lazy.

Not a "worthy" reason? Think again.



No need to think again, for me. You need to rethink what your responsibilities are and to who, if and when, you a get a job as a developer at a game company. As I see it, our jobs, as professional game developers, is to make an entertaining game for the player that makes money for us, the development company, and the publisher. And actually, if it makes money, it doesn''t have to be entertaining for the player, and you will still be a success to your development company, your publisher, and the industry. Our job is not to push the limits, but we often do to get the job done. The game players are failed only when they don''t get their money''s worth. Not when we don''t push their machines to the edge. The edge is not where most players machines are (How many of you guys have a P3 800?). It is also where many crashes and bugs come from when a game is released as finally a true sample of machines are put to the test. As an example, I think Q3 pushes the machine harder, but most thought UT was the better buy. Of course, at the same time, You Want To Be A Millionaire probably sold more copies and made more money than both of them. Maybe put together.

I never said to become lazy. In fact, what I said is I know when to use a goto. In a speed situation where it really matters (very very rare). I''d rather have most of my code work in my next project if I''m doing something I''ve done before, like a console, or a math library, or networking code, etc. Let me spend my time writing the new graphics engine, the new AI, and the new game code. Others had already mentioned the faults of using gotos so I didn''t recover that ground.

Plus, don''t forget, just like kids trying to be a pro-basketball player, most won''t, and neither will most of those on these boards. I''m already a professional designer/developer, hoping to get back in to games professionally, and I can tell you that speed is not an issue for 99.9% of all code written. Not an issue in at least 80% of a full game. Reuse(hurt by gotos). Ease of another picking up how to work with it(hurt by gotos). Reliability (hurt by gotos). All are more important than speed, almost always.

I say use a goto if you want, but understand why your doing it and whether it really pays off. Hell, yes, if it doubles frame rate, use it. No, if it gives you .00001% frame rate increase. It is poor style, poor design, and problematic for support down the road. Other than that its a perfectly OK keyword.

Mike Roberts
aka milo
mlbobs@telocity.com

Share this post


Link to post
Share on other sites
RWarden    118
Download the source code to the original Zork. Trust me, you''ll never even be tempted to use goto again .

-RWarden (roberte@maui.net)

Share this post


Link to post
Share on other sites
mossmoss    326
quote:

btw what''s a blue programmer?



A character rejected from Atari''s Gauntlet game...

quote:

"goto is EVIL!!!" they say. Has anybody noticed that exception handling (try/catch/throw statements)--and ''throw'' in particular--are really stylized goto statements? Stick a label where the catch() is, change ''throw'' to goto and it works exactly the same.



Incorrect. In previous years this was the case, when compilers didn''t correctly support exception handling and/or implemented it using calls like setjmp.

But C++ exception handling will unwind the stack and call object destructors as needed, something very important but not handled by goto. You also have the option to throw objects; this can be emulated with goto using globals, but exception handling is much cleaner and safer.

quote:

And a car probably can run on three wheels which saves you time rotating the tires. Faster doesn''t make right. Quality before quantity.



True... but saving typing can sometimes be a measure of quality. If I have a series of nested conditionals several layers deep, it can be cleaned up, made more readable, safer (by not having to retype various sections, or worry about braces, or about spacing and indentation in an attempt to make things readable, etc) by using goto. No, not always, but certainly sometimes. Your car analogy is good in many cases, but not all.

quote:

Hey, I resemble that statement at it''s full of bull! I started with BASIC in 1980, before there was a C for the masses and before C++ even existed.



Unfortunately, it''s not full of bull. I started similar to you: programming in BASIC in the early eighties for many years before experiencing C. I would also claim, as you do, to not have abused goto statements in neither BASIC nor C/C++. However, take my general statement for what it is: general and not all-encompassing. I apologize for not being clear in that respect in my original post.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
There are always going to be a debate about if and when to use a goto, but here is a good example when a goto makes things cleaner. Both of these functions do the same thing, however the second one is more readable (IMHO). (Sorry for the long post)

void InitializeSounds( void ) {

OSErr errorCode;


errorCode = LoadSound( kSoundID1 );
if ( sndNotFoundError == errorCode ) {

SoundCleanup( );
ErrorMessage( kBadErrorType, "Could not load sound resource\0" );
QuitClean();

}

errorCode = LoadSound( kSoundID2 );
if ( sndNotFoundError == errorCode ) {

SoundCleanup( );
ErrorMessage( kBadErrorType, "Could not load sound resource\0" );
QuitClean();

}

errorCode = LoadSound( kSoundID2 );
if ( sndNotFoundError == errorCode ) {

SoundCleanup( );
ErrorMessage( kBadErrorType, "Could not load sound resource\0" );
QuitClean();

}

...

errorCode = LoadSound( kSoundID23 );
if ( sndNotFoundError == errorCode ) {

SoundCleanup( );
ErrorMessage( kBadErrorType, "Could not load sound resource\0" );
QuitClean();

}

}


And here is the version with the gotos.


void
InitializeSounds( void ) {

OSErr errorCode;


errorCode = LoadSound( kSoundID1 );
if ( sndNotFoundError == errorCode ) goto InitializeSoundsError;

errorCode = LoadSound( kSoundID2 );
if ( sndNotFoundError == errorCode ) goto InitializeSoundsError;

errorCode = LoadSound( kSoundID3 );
if ( sndNotFoundError == errorCode ) goto InitializeSoundsError;

...

errorCode = LoadSound( kSoundID23 );
if ( sndNotFoundError == errorCode ) goto InitializeSoundsError;


InitializeSoundsError:

SoundCleanup( );
ErrorMessage( kBadErrorType, "Could not load sound resource\0" );
QuitClean();

}


Just my $0.02

Quattro

Share this post


Link to post
Share on other sites
Stoffel    250
True-life confessions of an NT-driver programmer:

Windows DDK for NT doesn''t support C++, only C. Say you need to allocate two or three objects using malloc in a function, then you need to perform 10 or 15 checks using those objects. If any check fails, all objects need to be free''d. You see this every time:
if (!some_test)
{
free (obj1);
free (obj2);
free (obj3);
return EINVAL;
}

..or, well, you suck it down and you goto freeall.

BTW, we didn''t do this. We really wanted to, but we couldn''t bring ourselves to use a goto statement in our code. So our code is (5 * 15 = ) 75 lines longer than it really needs to be, but we leave it that way.

However, it''s interesting to note that the example driver given by the DDK reference uses gotos.

(if microsoft does it, it must be ok, right?)

Share this post


Link to post
Share on other sites
Strife    374
You know, goto could be ok, if people would use it right. The problem is, most of the time when someone would want to use it, they''d use it WAY too much and it would screw things over a lot. But goto isn''t all that bad, if used sparingly. In fact, it can even be a little useful, in some VERY isolated circumstances. I never use it though

If you code it, they will come...

Commander M
(a.k.a. Crazy Yank)
http://commanderm.8m.com
cmndrm@commanderm.8m.com

Share this post


Link to post
Share on other sites
Queasy    157
for that guy who posted the InitializeSoundsError code example:

You could''ve made InitializeSoundsError a function. notice that as your program executes, even if no test fails, it will go right through your label and run that SoundsError portion even when there are no errors. You could easily combat that with a break or return call, but hey, doesn''t that make it more... unreadable?

hmm...

~Queasy.

Share this post


Link to post
Share on other sites