-
May 18th, 2009, 03:05 AM
#1
Using goto in c++ code
This may be a hot topic but I am interested in knowing what the general thought about this is. When I started to learn programming I was taught to never use goto's in the code (c++) and that this was an old way of programming.
Today, I'm working with an old c/c++ application that uses this goto command quite a lot and so I'm starting to wonder if it is not such a bad idea, at least in this case.
As an example of how it is used
Code:
int SomeFunction(int parameter)
{
int retVal = FALSE;
if (!Initiate())
goto ERROR_END;
if (!AllocateMemory())
goto ERROR_END;
if (!RunAnalysis())
goto ERROR_END;
return TRUE;
ERROR_END:
ReleaseMemory();
return FALSE;
}
In this case it is to me quite useful and makes the code more readable. Of course one could switch this to a series of if else statements but to me it would make the code more incomprehendable.
Any comments on this?
-
May 18th, 2009, 04:00 AM
#2
Re: Using goto in c++ code
Ok,
just to document the answer to this question I will put this here.
I read a few sections in the book Code Complete and found that it was actually one of the cases where a goto statement could be at its best use. That is, when performing error checks and clean up after an error.
One alternative to this is to use try-catch statements, but since I cannot rewrite the code that I already have I will keep using the goto standard that is used.
-
May 18th, 2009, 04:06 AM
#3
Re: Using goto in c++ code
Originally Posted by Ergodyne
Today, I'm working with an old c/c++
Which is it, C or C++?
Also, you should have posted this in the non-Visual C++ forum. Nothing in your code suggests anything to do with the Windows API.
Who releases the memory when RunAnalysis() returns? Does Initiate() allocate memory? If not, does ReleaseMemory() make sense when you did a "goto" from Initiate()?
We need more context as to what those functions do, as the goto's would be totally unnecessary with correct usage of RAII.
Regards,
Paul McKenzie
-
May 18th, 2009, 06:29 AM
#4
Re: Using goto in c++ code
I've been programming in C for 12 years then C++ for 9.
I used goto once (and I mean one goto) when I started learning C and I've never had reason to use it since.
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
-
May 18th, 2009, 07:11 AM
#5
Re: Using goto in c++ code
I must echo these last two posts.
RAII solves the issue without goto in this example, and is even more reliable ongoing. If someone comes along to expand this code, it is up to them to understand why the ReleaseMemory is called. An object implementing RAII would handle this without fail.
Notice, too, how retval isn't used. I smell an oversight in design - as in I see a ReleaseMemory, but where was it allocated in the first place?
I also see no clear indication of even a weak guarantee; exception safety is more than questionable, probably non-existent.
In 29 years (I have to keep updating my count) I don't recall using goto outside of example.
I don't think the keyword or what it does is the problem. Goto is implied by nearly every close backet "}" character. C was originally design as a kind of assembler, and branching is simply a part of the way CPU's work.
I think the reason a vast majority of seasoned developers loath goto is what happens in the context of it's use. I've never found it to increase speed, utility or readability (though I agree it doesn't always impede any), but I've also found it was never required.
Famous case point is Knuth's use of goto in a performance illustration. It's cited around here in the last month or so. A loop, using goto, runs faster based on a simple optimization - it's occasionally used as an example in defense of goto. The pseudo code is in Pascal notation. However, even in this case, the reason the loop is faster is because the increment of the loop is advanced by 2 each time, not by 1, and the test runs on two consecutive elements in the loop. The optimization works as well inside a for loop, without goto - and the code even looks clearer.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
-
May 18th, 2009, 09:22 PM
#6
Re: Using goto in c++ code
Originally Posted by Ergodyne
Any comments on this?
Use goto to your heart's desire.
There's still quite a few of us who think the jump is coming to us. Heil.
-
May 19th, 2009, 07:45 AM
#7
Re: Using goto in c++ code
It is good programming style to use the break, continue, and return statement in preference to goto whenever possible. Since the break statement only exits from one level of the loop, a goto may be necessary for exiting a loop from within a deeply nested loop.
But why would you want to ReleaseMemory if the Memory aint allocated?
It would have been nice to see what the functions does too.
I see that if AllocateMemory returns true it must be Released after RunAnalysis, i guess, if not then you dont have to release any memory.
this is your function without the goto statement:
Code:
int SomeFunction()
{
if (!Initiate() || !AllocateMemory() || !RunAnalysis())
{
ReleaseMemory();
return FALSE;
}
return TRUE;
}
Last edited by ruderudy; May 19th, 2009 at 08:27 AM.
-
May 19th, 2009, 06:38 PM
#8
Re: Using goto in c++ code
I don't think your sample is the best, because in your case you can write simply:
Code:
int SomeFunction(int parameter)
{
if (Initiate())
if (AllocateMemory())
if (RunAnalysis())
return TRUE;
ReleaseMemory();
return FALSE;
}
What you suggest is more intrresting in the case when multiple objects must be destroyed. Let's suppose you need
Code:
CreateObject1
CreateObject2
CreateObject3
In this case, if CreateObject1 fails, you simply return error.
If CreateObject2 fails, before returning error, you must destroy Object1.
If CreateObject3 fails, beforre returning error, you must destroy Object1 and Object2.
You can achieve that using the goto statement as follows:
Code:
if(!CreateObject1)
goto label1
if(!CreateObject2)
goto label2
if(!CreateObject3)
goto label3
return TRUE; // success
label3: DestroyObject2;
label2: DestroyObject1;
label1: return FALSE; // failure
But you can achieve the same behaviour without using goto:
Code:
{
int iErr;
if(!CreateObject1)
iErr = 1;
else if(!CreateObject2)
iErr = 2;
else if(!CreateObject3)
iErr = 3;
else
return TRUE;
switch(iErr)
{ // break statements intentionally ommitted
case 3: DestroyObject2;
case 2: DestroyObject1;
case 1: return FALSE;
}
}
The point is that goto statements are not necessary, although you can use them. Some people will accept them. But in the case of others, the goto statement will raise eyebrows. My advice is to avoid it. You can.
Last edited by srelu; May 19th, 2009 at 06:43 PM.
-
May 19th, 2009, 06:44 PM
#9
Re: Using goto in c++ code
Most teachers that I have run into, and even some books say that using goto creates spaghetti code and is looked down upon.
-
May 19th, 2009, 07:12 PM
#10
Re: Using goto in c++ code
.. goto creates spaghetti code...
I've heard this a lot, and in defense of the goto fans, I'd counter that it promotes it, but then I tend to be diplomatic about it.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
-
May 20th, 2009, 05:11 AM
#11
Re: Using goto in c++ code
Originally Posted by srelu
I don't think your sample is the best, because in your case you can write simply:
Code:
int SomeFunction(int parameter)
{
if (Initiate())
if (AllocateMemory())
if (RunAnalysis())
return TRUE;
ReleaseMemory();
return FALSE;
}
If you look at his code this is exactly what he wants.
I was just suggesting a simpler solution.
Anyway, back to coding
Last edited by ruderudy; May 20th, 2009 at 05:25 AM.
-
May 21st, 2009, 05:37 AM
#12
Re: Using goto in c++ code
Use it or don't use it, it's up to the programmer. The use of goto in OP's code would be ok by me if the function in which it's used is carefully written and not longer then...say 50 lines? And don't use it if more then one person works on the code.
I used it few weeks ago in some settings wizard I wrote where was essential that user can click back or next without any data loss, but that was for fun.
You just divided by zero, didn't you?
-
May 26th, 2009, 02:42 AM
#13
Re: Using goto in c++ code
Originally Posted by Ergodyne
This may be a hot topic but I am interested in knowing what the general thought about this is. When I started to learn programming I was taught to never use goto's in the code (c++) and that this was an old way of programming.
Not using goto is the theoretical foundation of high-level languages. It was proved that any program using goto could be replaced with a completely equivalent program without goto if a minimal set of control structures were used insted (like if-then-else, while-do, sequence, procedure, etcetera). This is also called the structured programming paradigm,
http://en.wikipedia.org/wiki/Structured_programming
This was very controversial at first. Many long-time assembly programmers felt that a language with just a few control structures would severely limit their right to freely express themselves. Others argued that it was worth it because restricting the programmer would reduce program complexity and thus lead to easier to understand and less error-prone programs. There was a very heated and infected battle and that's why the goto question is controversial even today. (old-timers in their late fifties can turn crimson red if they spot a goto because they get flashbacks from their youth when they put their lives on line in the war against the bogus goto).
As we know, structured programming and high-level languages won out eventually. Still the goto is there, both directly and in disguised form. Break, continue and multiple returns must be considered gotos. At least if you ask a hard-core anti-goto activist. It's because a goto-free control structure has exactly one entry and one exit point and those statements break that rule. Most people today consider them a very benign and accepted form of goto though.
So when is it okay to use an explicit goto? Well, the reason not to is that it increases the complexity of your code. It always does. So what you must ask yourself is whether it's worth it. Does the benefit of using goto offset the risks associated with more complex code? In my view it rarely does. The one time it's motivated is to handle errors, but then there's another systematic way to do that and that's to use exceptions. See Error Handling and Exceptions in the excellent book by Sutter & Alexandrescu called C++ Coding Standards.
Last edited by nuzzle; May 26th, 2009 at 05:46 AM.
-
May 30th, 2009, 01:49 AM
#14
Re: Using goto in c++ code
The most important thing to me is code readability. As long as any approach generate a clean code, I will use it. In C++, I will never thought of using goto at all because the language has better coding style. However, there are some situations in C, using goto will give a cleaner code.
Code:
int SomeFunction(int parameter)
{
if (!Initiate()) goto ERROR_END;
foo1();
if (!AllocateMemory()) goto ERROR_END;
foo2();
if (!RunAnalysis()) goto ERROR_END;
foo3();
return TRUE;
ERROR_END:
ReleaseMemory();
return FALSE;
}
If I am not using goto, the code would require some replications and looks more complicated than the above example.
Code:
int SomeFunction(int parameter)
{
if (!Initiate()) {
ReleaseMemory();
return FALSE;
}
foo1();
if (!AllocateMemory()) {
ReleaseMemory();
return FALSE;
}
foo2();
if (!RunAnalysis()) {
ReleaseMemory();
return FALSE;
}
foo3();
return TRUE;
}
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
May 30th, 2009, 09:18 AM
#15
Re: Using goto in c++ code
One of many possibilities:
int SomeFunction(int parameter)
{
int retVal = TRUE;
if (!Initiate()) retVal = FALSE;
else if (!AllocateMemory()) retVal = FALSE;
else if (!RunAnalysis()) retVal = FALSE;
if(!retVal) ReleaseMemory();
return retVal;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|