-
Is using goto a bad practice
Sad enough to say, my first experiences in programming were on a TI-83+ calculator. And as some of you may know labels and goto were the closest you could get to OOP on one of those. But that was then, this is now. Would you guys/girls agree (with my professor...) that using labels and gotos in C++ is a bad programming practice?
-
Re: Is using goto a bad practice
Quote:
Originally Posted by phosphorus
Would you guys/girls agree (with my professor...) that using labels and gotos in C++ is a bad programming practice?
I would say that "excessive" use of "gotos" is bad practice. There are however a coupld of cases where "goto's" are imho the best alternative, the most prominent one being the possibility to abort nested loops. Example:
Code:
void f()
{
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// do something
if (...) {
// abort both loops
goto afterloops;
}
}
}
afterloops:
// do something more
}
-
Re: Is using goto a bad practice
treuss, I tend to disagree with your example and, in my opinion, your way shows why goto's should be avoided at every instance - its lazy programming practice.
The code that you used as an example can easily avoid goto's, but does require extra effort in terms of thinking:
Code:
void f()
{
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// do something
if (...)
{
i=10; // or 9
break;
}
}
}
// do something here
}
This will still achieve what you want without the goto statement.
All in all, goto's should be avoided at all costs and there should be no reason for it.... in all my experience I have never used them and anyone who has, has been frowned up on.
Just my $0.02 worth
Regards
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Vaderman
This will still achieve what you want without the goto statement.
Except that your codes behaves differently.
If the values of i and j are needed for further processing you'll need a third variable storing the value of i.
- petter
-
Re: Is using goto a bad practice
-
Re: Is using goto a bad practice
Quite true wildfrog. :thumb:
Regards
-
Re: Is using goto a bad practice
This thread has "flame war" written all over it :)
Quote:
Originally Posted by phosphorus
Would you guys/girls agree (with my professor...) that using labels and gotos in C++ is a bad programming practice?
No, gotos are an invaluable tool for making your code unintelligible to other programmers and introducing subtle and hard to find bugs. Why would you want to give that up?
Seriously, there's a problem in C++ with gotos that they may skip over constructor calls, so at the target of the goto you are in a situation where a variable is in scope but hasn't been constructed. Fortunately, most compilers will warn you about this so you can avoid it. Other than that - feel free to use gotos. The more, the merrier.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Vaderman
All in all, goto's should be avoided at all costs and there should be no reason for it.... in all my experience I have never used them and anyone who has, has been frowned up on.
I have never used them; but in hindsight, I think my prejudice against goto was mere superstition. There is no harm done if it results in more readable code.
Quote:
Originally Posted by Vaderman
Code:
void f()
{
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// do something
if (...)
{
i=10; // or 9
break;
}
}
}
// do something here
}
"break" does not take you out of both loops.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Philip Nicoletti
The great goto debate ...
That was 4 years ago. I think it's time for a new one ;)
-
Re: Is using goto a bad practice
break does not break you out of both loops. You're correct on that point. Never suggested that it would. ;)
It will break out of the inner loop and since i=10 (or 9) it will then break out of the outer loop.
Regards
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Vaderman
treuss, I tend to disagree with your example and, in my opinion, your way shows why goto's should be avoided at every instance - its lazy programming practice.
The code that you used as an example can easily avoid goto's, but does require extra effort in terms of thinking:
It is of course your good right to disagree with me but I do not consider your example better code than mine. Your example is imho a good example of what oddities programmers sometimes code, just for the sake of avoiding gotos.
Yes you can always avoid gotos. Just as you can always avoid for-loops, or do-while constructs. Just, for what sake?
If you look at our both code examples and think away any comment, my example is very self-documenting (goto afterloops), while yours will put a beginner programmer (or someone who reads over the code too quickly) at problem, because "i=10;" is not a very common neither clear way to end a loop, "i=9;" is probably even worse (though more correct).
So, this is my opinion, as stated you have the full right to disagree (would be boring if all agreed on the same thing).
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Sahir
That was 4 years ago. I think it's time for a new one ;)
Why, the C++ standard hasn't changed since 1998 ;)
-
Re: Is using goto a bad practice
I have never used a goto in any *production* program that I have written. I have avoided them at all cost and written complex loops to get around using them.
Having said that, I believe that goto statements do have their place and are not by definition "bad". I think that there have been 1 or 2 times that I should have used a goto when I didn't because I was told by other programmers/books/professors that they are bad.
Another "bad programming practice" that I think is more accepted now is having more than 1 return from a function. This one I really don't worry about at all. Just as long as the code makes sense, then I don't worry about how many returns statements are in a single function call. In fact, It is much more difficult to code a single return, when multiple returns make sense, than to code a loop (or something else) when a goto makes sense.
Sincerely,
Kendall
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Sahir
[...] There is no harm done if it results in more readable code.
The problem is that you've just described the null set.
-
Re: Is using goto a bad practice
In Javascript (ECMA Script 3. ed) you got break and continue statements just as in C/C++, but in addition you can add an optional label to the keyword:
and
Code:
outerloop:
while (a)
{
while (b)
{
if (someCondition)
break outerLoop;
}
}
This seems like an attempt to avoid the use of goto and other messy code to break/continue nested loops. What do you anti-goto'ers out there think of such a construct?
- petter
-
Re: Is using goto a bad practice
Quote:
Originally Posted by wildfrog
In Javascript (ECMA Script 3. ed) you got break and continue statements just as in C/C++, but in addition you can add an optional label to the keyword.
Looks like this was taken from Java. Although I thought these two languages don't have anything in common except for four letters in the name.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by treuss
Looks like this was taken from Java. Although I thought these two languages don't have anything in common except for four letters in the name.
Those two (or more) languages are equal in many ways. My example was with Javascript in mind, but looking at the spec I now see that Java supports labeled break/continues as well.
- petter
-
Re: Is using goto a bad practice
Quote:
Originally Posted by phosphorus
Would you guys/girls agree (with my professor...) that using labels and gotos in C++ is a bad programming practice?
Asking this question in a C++ forum dominated by OOP guys is like throwing a bone to a dog. :D IMHO it is bad if you are doing in an OOP project. But C++ is not all about OOP so I wouldn't say that goto is essentially bad.
-
Re: Is using goto a bad practice
This has been debated here and many other places before. In every thread I've ever seen, the conclusion has been that goto makes code less maintainable. From this perspective, goto is bad to use.
However, if you need highly optimized code where every CPU cycle counts and profiling has proved that the use of goto will get rid of a bottleneck, then the use of goto is OK. But this is pretty darn rare!
-
Re: Is using goto a bad practice
Well the absolutely worst thing you can do with a goto is if the target label appears before the goto call, i.e. the logic goes back up instead of down.
If you see code like that, then the person who coded it should be fired on the spot.
Regards,
Paul McKenzie
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Paul McKenzie
Well the absolutely worst thing you can do with a goto is if the target label appears before the goto call, i.e. the logic goes back up instead of down.
If you see code like that, then the person who coded it should be fired on the spot.
Actually, I have worked on projects where this was necessary! :eek:
But this was an embedded C (not C++) application running on a DSP chip with a limited amount of program memory and only done so after all other more maintainable attempts proved too costly (in program memory space) to implement.
-
Re: Is using goto a bad practice
I have seen goto used in the source code of the gcc compiler ( 10 years ago). The code was generated by lex and yacc and thus was quite safe to use as long as you didn't have to change it.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by PadexArt
as long as you didn't have to change it.
Exactly, gotos are difficult to maintain!
-
Re: Is using goto a bad practice
My last word on the subject: goto's are bad and should not be practised anywhere, anytime and under no circumstances. For all you junior programmers out there, take note.
John
-
Re: Is using goto a bad practice
Quote:
Originally Posted by Vaderman
...The code that you used as an example can easily avoid goto's, but does require extra effort in terms of thinking:
Code:
void f()
{
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// do something
if (...)
{
i=10; // or 9
break;
}
}
}
// do something here
}
This will still achieve what you want without the goto statement.
All in all, goto's should be avoided at all costs and there should be no reason for it...
This is probably the WORST argument against goto statement I've seen (and I did see a lot).
Your code is far more difficult to understand / maintain. It violates much more important rule: the loop variables should NOT be reassigned within the loop.
This is the most artificial way to avoid an otherwise harmless, clearly stated attempt to break from nested loops, simply for religious reasons.
I would also dare to say that almost nothing should be avoided "at all costs" - the cost just might be much greater than a potential (often misestimated) loss.
<EDIT> P.S. Even better, to my surprize, I found that if you have an object created at "// do something" line, its destructor is called when goto is executed!
-
Re: Is using goto a bad practice
i recently wrote some code like that i was tempted to use goto but bea
cause of the hysteria related to it i didn't. I always do the following:
Code:
void f()
{
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
// do something
if (j==10)
{
break; //we got the result get the hell out
}
if(...)
break; //add a conditional here usually identical to the if need to exit the other loop
//go go go go
}
}
// do something here
}
Rich
-
Re: Is using goto a bad practice
here is a very readable way to breakout of nested loops.
Code:
for(size_t i = 1, break_loops = 0; i < 10 && !break_loops; i++)
{
for(size_t j = 0; j < 10 && !break_loops; j++)
{
if(WHAT_EVER)
break_loops = 1;
}
}
goto is just a tool. Like every tool it has the potential to be used correctly or incorrectly.
The only possible arguement here is that it is too easy to use goto incorrectly.
//In the interest of flame:
if you use goto then you are guilty of bad programming style.
Just as, if you use MFC, say CArray instead of vector, you are guilty of bad programming style by proxy
There are no exceptions. That is the way it is...
-
Re: Is using goto a bad practice
Back to the original question, it is easy to answer:
NO
Using goto in C++ must not be a "practice", if practice refers to a habit, or a way of usually doing things.
I read the definitions of practice.
practice:
knowledge of how something is usually done; "it is not the local practice to wear shorts to dinner"
Furthremore, phosphorus said that he programmed with a TI 83+ calculator, where goto is a much used control structure.
It is obvious that if we answer that "it is okay to use goto", he will be tempted to write a C++ program using the same control-structure design that he was using with his calculator.
It is a an abuse of goto.
Actually, someone who learns C++ should ignore the existence of goto (especially if he used to write programs with a goto-full language).
Then, when he is an experienced C++ programmer, he can, sometimes, use goto when alternatives are worse (as the alternative Vaderman showed).
He should, however, keep in mind that a program containing more than very few gotos, is flawly designed.
PS: for the break-from-two-nested-loops thing:
When writing a C++ program, a return statement is usually enough to double-break, because a good programmer writes small routines which do a specific task, and it is seldom to have to do more work after a double-for-loop, except, perhaps, resource deallocations, but if the program has to be exception-safe, RAII is used, and no explicit resource deallocations occur.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by SuperKoko
PS: for the break-from-two-nested-loops thing:
When writing a C++ program, a return statement is usually enough to double-break, because a good programmer writes small routines which do a specific task, and it is seldom to have to do more work after a double-for-loop, except, perhaps, resource deallocations, but if the program has to be exception-safe, RAII is used, and no explicit resource deallocations occur.
very good point although it somewhat avoids the issue.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by SuperKoko
Then, when he is an experienced C++ programmer, he can, sometimes, use goto when alternatives are worse
I second that.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by souldog
here is a very readable way to breakout of nested loops.
Code:
for(size_t i = 1, break_loops = 0; i < 10 && !break_loops; i++)
{
for(size_t j = 0; j < 10 && !break_loops; j++)
{
if(WHAT_EVER)
break_loops = 1;
}
}
If you'd have a little more code in your loop (like in some real life example):
Code:
for(size_t i = 1, break_loops = 0; i < 10 && !break_loops; i++)
{
for(size_t j = 0; j < 10 && !break_loops; j++)
{
if(WHAT_EVER)
break_loops = 1;
}
// MORE CODE HERE
}
the part "// MORE CODE HERE" will still be executed, unless, of course, you add multiple tests for "break_loops", wich doesn't help the things. Think about more than two nested loops. If the code is trivial - almost any solution will be readable.
About SuperKoko's suggestion of multiple return statements - I believe it isn't much better than goto's, and sometimes - much worse.
P.S. When we are done with goto, lets talk about use of tabs vs. spaces for indentation.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by VladimirF
P.S. When we are done with goto, lets talk about use of tabs vs. spaces for indentation.
Tabs are evil when you have to port code between multiple operating systems.
flat out evil.
-Kendall
-
Re: Is using goto a bad practice
Quote:
Originally Posted by kenrus
Tabs are evil when you have to port code between multiple operating systems.
flat out evil.
-Kendall
Along those lines...
One of the best, unintentional, things my employer did for my productivity was to purchase a monitor that can be rotated to portrait orientation.
I am able to see so much more code on the screen at one time.
As time went on, 2 (out of 3 - the 3rd is a mainframe programmer, and well you know...) of the programmers around me have also rotated their monitors to the portrait orientation.
-Kendall
-
Re: Is using goto a bad practice
Quote:
Originally Posted by kenrus
Tabs are evil when you have to port code between multiple operating systems.
flat out evil.
-Kendall
yah, I know I am going to pay dearly for that bad habit in the future.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by kenrus
Tabs are evil when you have to port code between multiple operating systems.
What OS today can't handle tabs???
When you use tabs for indentation, I can view YOUR code the way I like it! And if your editor can't expand them to whatever number of spaces you want - shame on it!
-
Re: Is using goto a bad practice
Quote:
Originally Posted by kenrus
Tabs are evil when you have to port code between multiple operating systems.
flat out evil.
No. The only flat out evil thing is mixing tabs and spaces for indentation!
-
Re: Is using goto a bad practice
Quote:
Originally Posted by VladimirF
What OS today can't handle tabs???
When you use tabs for indentation, I can view YOUR code the way I like it! And if your editor can't expand them to whatever number of spaces you want - shame on it!
I am not aware of any operating system that can not handle tabs. My complaint comes from the fact that different IDEs have different spacing for tabs. Most have an option where you can set the spacing for tabs, but that kind of option tends to be obscure.
-Kendall
-
Re: Is using goto a bad practice
Ah goto... I remember a lot of gotos on Apple II Basic ;)
I remember programming my TI 85 calculator in H.S. ;)
I've heard it is bad and back around the 70's(I think) they moved away from goto and developed structured programming because of lots of bugs and problems tracing those bugs.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by treuss
No. The only flat out evil thing is mixing tabs and spaces for indentation!
i agree =). i use tabs all the time and have never met a situation on any platform where this caused an issue. imo it produces more readable code and is certainly easier than spacespacespace all the time
as for gotos, i'm pretty sure i commented in one of those other threads back in the day but i think they should be avoided as much as possible in c++. BUT, as someone else has already said, an experienced programmer using gotos is a very different story than a beginner and i think this designation is where the answer lies. for someone who can think through in their head all the implications of using a goto and all the alternatives available it probably isn't that big of a deal (aside from the personal beliefs it offends)
-
Re: Is using goto a bad practice
Quote:
Originally Posted by filthy_mcnasty
as for gotos, i'm pretty sure i commented in one of those other threads back in the day but i think they should be avoided as much as possible in c++. BUT, as someone else has already said, an experienced programmer using gotos is a very different story than a beginner
Yep - it's the difference between a program that simply fails and one that brings down the system with it.
Quote:
Originally Posted by filthy_mcnasty
[...]. for someone who can think through in their head all the implications of using a goto and all the alternatives available [...]
Another description of the null set :)
-
Re: Is using goto a bad practice
Hi,
I know that the following is not what throw and catch were designed to do, but is it not possible to use throw and catch as an alternative to goto?
For example in the code below, method 1 breaks out of the double for loop using the goto, whilst method 2 breaks out of the double for loop using throw and catch.
What are your thoughts on this? Thanks.
Code:
#include <iostream>
using namespace std;
const int asize = 5;
int main(void)
{
//Method 1 - using goto to exit double for loop
for(int row = 0; row < asize; ++row){
for(int col = 0; col < asize; ++col){
cout<<"row = "<<row<<", col = "<<col<<endl;
if(row==2 && col==2){
goto escape;
}
}
}
escape :
cout<<"Finished method 1\n";
//Method 2 - using throw and catch to exit double for loop
int escape=0;
try{
for(int row = 0; row < asize; ++row){
for(int col = 0; col < asize; ++col){
cout<<"row = "<<row<<", col = "<<col<<endl;
if(row==2 && col==2){
throw escape;
}
}
}
}catch(int){}
cout<<"Finished method 2\n";
system("pause");
return(0);
}
-
Re: Is using goto a bad practice
goto is a tool and since there is no proof for whether its usage is correct or not, use it where it is needed and be prepared to be wrong in your decision :)
-
Re: Is using goto a bad practice
Consider what happens if another function in try block also happens to throw an integer. That throw will trigger your goto replacement instead of up to the next matching catch block higher up the stack.
Anyway, if you are going to use goto-like behavior, use a goto! At least you'll be clear in your intentions!
The problem most people have with goto is that the logic for a goto is disconnected from the logic for a loop. For while, do-while, and for loops, the logic is intimately connected to the loop (specifically where the loop is defined). This connection is important because it makes code more maintainable. Without the connection, it is very easy to make spaghetti code.
My rule of thumb: The only time one should use goto is when writing time-critical code and profiling shows that it is not possible without gotos. (If your time-critical code will improve by use of goto's, it is likely already going to have some other uncommon constructs that will be difficult to maintain. And yes, I have come across these cases.)
- Kevin
-
Re: Is using goto a bad practice
Hi Kevin,
The problem that you mentioned above can be very easily circumvented by defining a
unique identifier (e.g. a class), and then throwing that. I have rewritten
the code below to show what I mean :
Code:
#include <iostream>
using namespace std;
const int asize = 5;
namespace {
class unique{
} jump;
};
int main(void)
{
//Method 1 - using goto to exit double for loop
for(int row = 0; row < asize; ++row){
for(int col = 0; col < asize; ++col){
cout<<"row = "<<row<<", col = "<<col<<endl;
if(row==2 && col==2){
goto escape;
}
}
}
escape :
cout<<"Finished method 1\n";
//Method 2 - using throw and catch to exit double for loop
int escape=0;
try{
for(int row = 0; row < asize; ++row){
for(int col = 0; col < asize; ++col){
cout<<"row = "<<row<<", col = "<<col<<endl;
if(row==2 && col==2){
throw jump;
}
}
}
}catch(unique){}
cout<<"Finished method 2\n";
system("pause");
return(0);
}
-
Re: Is using goto a bad practice
I think it the answer is it depends. I think in most languages 99.8 percent of the time you should not be using gotos. That being said once in a very great while you might have nested switches or something where a goto would be easier to read then most other options in that case i think its ok. If your programming in assembly then obviously you cant avoid gotos since a label and a jmp instruction is the same thing as a goto. Gotos are fundamental to computers really so theres no avoiding them completely. I mean its translated to assembly with labels and jumps anyways.
-
Re: Is using goto a bad practice
Using exceptions for that is evil.
Not only is it perversing the system, but it's also likely to have incredibely bad performances. Ssomething like more than 200 microseconds for each throw statement... More for "zero overhead" exceptions.
In C++ exceptions must never be thrown in the normal control flow of a program.
There are enterprises who use tools to log every exception in a file and never release the application before zero exceptions are thrown in the normal control flow of the program.
Gotos are evil. Ok. But perversions used to avoid gotos can be worst.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by wildfrog
In Javascript (ECMA Script 3. ed) you got break and continue statements just as in C/C++, but in addition you can add an optional label to the keyword:
and
Code:
outerloop:
while (a)
{
while (b)
{
if (someCondition)
break outerLoop;
}
}
This seems like an attempt to avoid the use of goto and other messy code to break/continue nested loops. What do you anti-goto'ers out there think of such a construct?
break can be implemented in terms of goto. And that is the kind of limitation that break suffers over goto and hence I feel the goto debate keeps popping up. This would be a nice feature and I have read discussions around something like that happening on clc++m.
-
Re: Is using goto a bad practice
I programmed in Fortran for 20 years, so I have a deep-rooted loathing for goto in all its forms, including break and continue. Gotos increase the time taken to understand and to maintain any piece of code. If I never see another one, it will be too soon.
-
Re: Is using goto a bad practice
Who ressurrected this one and a half year old thread? I'm sure we will see the goto statement being removed from the C++ standard sooner, than we will see this discussion reach a conclusion.
-
Re: Is using goto a bad practice
Quote:
Originally Posted by artella
Hi Kevin,
The problem that you mentioned above can be very easily circumvented by defining a
unique identifier (e.g. a class), and then throwing that.
[/code]
Wow, a unique class for every goto? That sounds much more maintainable than just using a goto! Then there's the argument about performance (which others have brought up).
But you obviously missed the point I made earlier. If you are going to use goto-like capabilities, then use a goto! Don't simulate a goto with features that aren't designed to be gotos. You'll only confuse other people who have to maintain the application.
- Kevin