Why is using goto so bad?

Started by
151 comments, last by MrPoopypants 21 years, 4 months ago
I refused to use 'gotos' back in my QBasic days. It seems so sloppy chasing those around. There really no use for them if you program logically.

Anonymous Poster: Nice example, how many times do you have 10 nested for loops? Before your program gets to that point it should be broken up into more modular units... Goto is the best option to escape from 5 out of the 10 for loops? Maybe... But 10 for loops isn't the best option...

I suppose in a trouble shooting situation goto's could serve a purpose... You'd catch me with my hand in Sedrick The Entertainers pants before you caught me doing that though. And despite what people will tell you, that IS long off...

And to whoever said their instructor doesn't let them use 'breaks' Your instructor is an idiot. In the real world it comes up. I can see him telling his class that just to make them have to think logically, but in the real world that's not sloppy or impractical. Same with using 'continues.' Kick your instructor in the nut cluster for me.

-Dennis

[edited by - anachronism on December 17, 2002 6:46:06 PM]
Advertisement
quote:Original post by Stan100
but still you can''t easily have a 200 line while- statement (unless it''s a tictactoe loop)

You shouldn''t have a 200 line anything- statement.


For those who believe in God, most of the big questions are answered. But for those of us who can''t readily accept the God formula, the big answers don''t remain stone- written. We adjust to new conditions and discoveries. We are pliable. Love need not be a command or faith a dictum. I am my own God. We are here to unlearn the teachings of the church, state, and our educational system. We are here to drink beer. We are here to kill war. We are here to laugh at the odds and live our lives so well that Death will tremble to take us -- Charles Bukowski
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
to origianl poster: don''t listen to your teacher, his plain stupid

goto:
very little use, but sometimes usfull, for example escaping from nasted loops, which has been totally scrued up in c and c++ (should there be break(0), break(1) ect. ???)

break:
very importand feature

you should avoid goto, not becouse it will make your code less readeable, but becouse it wil fuck up compiler optimizations, i think those, pure-code gurus don''t even know the real reason behind not using goto, still very little use for gotos

and nested loops are evil ??? what a engenius statement, lets be consistand and convert all double and more nested loops into function calls ! thats a great idea, and no break, so all escape conditions must be integerated into one, it will be much more readable !, people, write some code, and that you can tell bullshit supported by your own experience, not by some books written by guys that have been writing poems in c & c++, not real code

and i konow you can (sometimes) set a condition to be false to simulate break, by its: 1) less readable, 2) adds overhead
quote:Original post by SabreMan
A power loop is not justification for heavily nested expressions, and neither does such a pathological case make for a counterpoint. Heavily nested expressions are dreadful style.

It does, because the powerloop hides the heavy nesting. They''re still notionally nested, but the powerloop structure keeps it tidy.
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/
Your teacher is locked in his way of thinking. I always tell my students to use whatever tools suits their needs. The argument about bad coding habits is wrong. The argument of readability likewise. If programmers cannot handle following a code using goto then quite frankly they need to go back to school. As for debugging, you don''t need goto to have code explode in your face do you? There really is no reason why you should not use goto when it suits your needs. If you work in a team, make sure you comment that goto so it is easy to follow. Many times you don''t
even need to go there to read the code if it is properly commented. If find the lack of proper comments in coding a far bigger problem than the use of goto. Even John Carmack is using goto so why shouldn''t you?
quote:Original post by Anonymous Poster
Even John Carmack is using goto so why shouldn''t you?


Because, despite the fact that he''s bloody good at coding 3d engines, his style is awful. Carmack is undoubtedly a genius and as such can get away with it. Us lesser mortals should enforce good programming practice.



"That''s not a bug, it''s a feature!"
--me
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
quote:Original post by DrPizza
It does, because the powerloop hides the heavy nesting.

It does what? Make for a counterpoint? The point is that coding heavily nested loops is poor style. A power loop does not require coding heavily nested loops, and is therefore not a counterpoint.

I''ll elaborate my earlier statement for your special benefit: if you think it is acceptable general practice to heavily nest loops, then no amount of "goto" will make your style acceptable. Power loops have got sod all to do with it.
quote:
They''re still notionally nested, but the powerloop structure keeps it tidy.

I''m fairly sure it''s safe to assume the AP wasn''t talking about using goto to break out of "notionally nested loops". If he was, he still would not have justified goto.
quote:
Even John Carmack is using goto so why shouldn''t you?


You know, Carmack is a smart guy, but learn to think for yourself and come to your own conclusions. Blindly following a supposed "God" is a surefire way to never do anything of mention on your own.

quote:
I used this in my C++ project, and the teacher''s responce was: "we DO NOT use goto''s in this class.


goto''s like all other constructs have their place. goto''s place is just a very narrow and limited one. The only time I''ve ever atually needed a goto in C++ was to similate coupled recursion. This comes up a lot in simulating state machines, and there are more OO (State pattern) solutions to the problem, but there is a bit of overhead. Observe:


  int f(){    switch (/* ... */) {        case 0: return f();        case 1: return g();        case 2: return h();        // ...        default: return error();    }}int g(){    switch (/* ... */) {        case 0: return f();        case 1: return g();        case 2: return h();        // ...        default: return error();    }}int h(){    switch (/* ... */) {        case 0: return f();        case 1: return g();        case 2: return h();        // ...        default: return error();    }}int error(){    // ...}  


Each function represents a state of the machine. Based off of some input the machine calls the next function and essentially changes it''s state. The problem is without tail-call optimization each state pushes another activation frame onto the call stack. Since I should be able to change states forever, this presents a problem. The call stack grows and grows until it runs out of memory.


  int fsm(){    int reg;f:    // ...    switch (/* ... */) {        case 0: goto f;        case 1: goto g;        case 2: goto h;        // ...        default: goto error;    }g:    // ...    switch (/* ... */) {        case 0: goto f;        case 1: goto g;        case 2: goto h;        // ...        default: goto error;    }h:    // ...    switch (/* ... */) {        case 0: goto f;        case 1: goto g;        case 2: goto h;        // ...        default: goto error;    }error:    // ...done:    // ...    return ret;}  


This version simply jumps from label to label and doesn''t touch the call stack. It does have the drawback of posing a difficulty in differentiating between a large number of states as the function body becomes ridiculously large. It is easier to share data between states though without having to resort to global variables, function parameters or any other concoction. Look at the output of lex and yacc someday and you''ll see more of this.

The above was a very specific example. goto''s are not useful for general programming and 99% of the time they do more harm than good. But nonetheless, they do have their uses.

quote:
Unless you''re using a powerloop.


Powerloop?

Also, on the subject of not needing continue and break... well, IMHO, it''s easier to use them. You can throw everything in the loop condition, but putting some code inside the loop in terms of:


  vector<int> vec = /* ... */;vector<int>::iterator i;int item = /* ... */;for (i = vec.begin(); i != i.end(); ++i)    if (*i == item) break;for (i = vec.begin(); i != i.end() && *i != item; ++i);  


I tend to prefer the former, but that''s a matter of taste, or lack thereof.
I don''t use goto''s. Not for any particuliar reason, just because everybody says not to, and I haven''t had any need to use them. So I''m not going to try and weigh in and pass judgement as to whether they are ok or not. But there is one thing this topic makes me curious about. I used to be an intern at a database company, where I monitored builds and ran tests and other crap intern jobs. I noticed that they used goto''s frequently to jump to some common error handler. They''d set some global errornumber or something than they''d goto OnError, or something or other, I can''t recall. This all seemed perfectly logical to me at the time, so I just figured that that must be an exception to when it was ok to use goto''s. But now I wonder... would throw''ing an exception accomplish the same thing?

I guess my question is, for someone who habitually avoids goto''s, is there really any case where a goto would be better than some other option, like a throw or an inline function or something? In other words, is there ever a case where avoiding goto''s out of generally considered good programming style costs you anything?
On the rare occasion you think "Shit, how do I do this without using a goto?" and spend more time trying to implement a complex solution than you do implementing the purpose of the function/method you're working with - you should probably just use a goto. However, as pointed out in Code Complete [McConnell], you should limit it to breaking out at the end of a loop statement or whatever - that is, don't use a goto that's going to potentially lose somebody reading your code.

The problem with gotos is readability. If you come back to your goto-ridden code after a year or so, and find yourself scrolling up down left and right to find all the labels referenced by the gotos and what not, it should be obvious to you that it's probably not the best thing to do.

People have also mentioned breaks. Breaks are more common, and less dangerous that gotos because it's more or less a 'goto' to the end of a loop - as described above. But they are by no means completely harmless: long while/for loops (argue what you will, but sometimes they do happen) with many break statments (or even short while/for loops with many breaks I suppose) can be _CONFUSING_ beyond belief. You may get to a point where you don't know where your 20000 iteration loop will exit.

Anyways my little rant, me out.

Tom L

[edit - little spelling fix]

[edited by - krumms on December 17, 2002 12:33:37 AM]
refrain_from_stupidity( &me );

This topic is closed to new replies.

Advertisement