Quick question about goto in C++

Started by
33 comments, last by starmole 18 years, 8 months ago
Maybe people will recognize me from my ill-informed python vs. c++ post in For Beginners. Hehe, had to start somewhere. Anyway, I decided I'd give C++ a little more of a solid shot, and in my studies, I encountered the goto command, which sounds real nice n' all, but the tutorial/book I'm reading recommends against using it, as goto is 'considered a poor programming style.' Not much explanation was given, so I'm curious why it's favorable to use loops instead of goto. Thanks in advance, to any potential answerers :D
Advertisement
Readability: each of the loops (while, do while, for) has well-known and explicit functioning, and you know just by looking at the indentation what block of code is "inside" the loop, as well as when and how it will be executed.

On the contrary, goto has a much more wide range of possibilities, which means that upon encountering a goto in code, the reader will have to spend some time figuring out what the code does exactly. There is also the possibility of error while reading or writing the code, because more things can go wrong with goto than with a loop.

This does not exclude the use of goto in situations where this use is widely known and accepted in the industry, such as error management in C (by having all errors go to a portion of code at the end of the function that cleans up the data).

I do not know of any widely known and accepted use of goto in C++, however, so by using it you expose yourself to the risk of making your code more unreadable and bug-prone than if you had gone with loops.
Yeah, I hadn't noticed, well, anyone using it in C++, I assumed it was because it was potentially dangerous. Makes sense, though. Thanks for the answer :)
There's a story -- not sure how true it is -- that in the first version of Java, if you used goto, the following error message would appear:

KeywordTest.java:4 'goto' not supported. Duh.
You have no business programming in Java. Begin erasing
Java Software Development Kit? (Yes/OK)
1 life altering error

says it all, really... [grin]
If at first you don't succeed, call it version 1.0You don't stop playing because you get old; you get old when you stop playing.
From the classic article: Go To Statement Considered Harmful.
I agree with you, but in a situation like this it becomes pretty useful:
while (...){   while (...)   {      if (...)         goto endWhiles;   }}endWhiles:


I know there are other ways to get around this but this seems the simplest.
int function(){  do stuff  for ( more stuff )  {    do more stuff...    if( error )     {      return_code = -1;      goto return_label;    }  }  return_code = 1;return_label:  return return_code;}


I use that a lot.
I'm not sure if it is the same in C++, but while coding it is best to use loops because the computer stores the start and end of the loop, making it very fast to keep running the loop until conditions have been met. When a goto comes up the computer has to look through the code to find where you are looking for, which takes up a bit more time than a loop would. It also seems to be prone to small memory leaks which can further slow down your code.
Not trying to re-ignite a recent flamewar, but a goto is handy as a multilevel break, among other things.

int x,y,z;for(x=0;x<100;++x){   for(y=0;y<100;++y)   {      for(z=0;z<100;++z)      {         foo(x,y);         if(bar(x,y)) goto loop_done;         quux(x,y);      }   }}loop_done:


They are also extremely useful is machine-generated code. In particulatr, parser generators (like bison) which translate the grammar into a state machine, and the state machine into actual C code - riddled with gotos.

As for goto being evil, well... people are taught that gotos are evil, therefore they don't use them, thus they don't learn to use them. So when they encounter code that includes a gotom they are baffled and, as ToohrVyk pointed out, are forced to think about how the goto work. The readability of the code is thus reduced, before you even start considering whether the use of the goto was justified or not (which they are told is never the case). It's a self-fulfilling prophecy and a self-propagating meme rolled into one neat package. You accept what you were told at face value (or get graded down in your assignments) and in turn, repeat what you were told to new programmers without accounting for changing circumstances (and without updating their skills).

There is also a fear of "spaghetti code", where gotos jump all over the place. Forty years ago, that was a valid concern, considering both the actual languages in use (e.g. having line numbers mean you can potentially do a goto to any point in the program without having any hint at the destination line that there is code that jumps here or not) and the tools available (modern IDE = gold). Fortunately, in C++, you are limited to local gotos (can't leave the function), so any potential spaghetti code is limited in scope.

Beyond that, it's a question of discipline and of doing the Right Thing, just like public/private members, macros, multiple inheritance, fixed-size buffers, variadic functions, virtual functions, exceptions, operator overloading... there are plenty of controversial features in the languages, most of which can be misused or used constructively. The designers of Java chose not to include operator overloading because (generally speaking) someone, somewhere, might define + to mean -. Can you? Yes. Should you? No.

Can a goto be useful? Yes. Should it be the first thing you reach for? No.

Assignment: What were the popular languages when Dijkstra's paper was written? Reframe the goto question in the context of those languages. Compare and contrast with current programming techniques, paradigms and languages. You have 180 minutes. [wink]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by 999999999
I agree with you, but in a situation like this it becomes pretty useful:
while (...){   while (...)   {      if (...)         goto endWhiles;   }}endWhiles:



I would rewrite this code using a function around the outer while. Not because there is a goto in it, but because in 99.9% of while loops the only ways to get out is:
- a break in the loop
- the condition becoming false
- the function returning

(Also, exceptions, but they do not interfere with the algorithm since they skip everything back to a safe state).

Your code is the 0.1% situation where an additional case has to be considered, and it's the kind of thing that is tough on the maintenance programmers, especially when they are not used to this control structure.

This topic is closed to new replies.

Advertisement