Question:
Using the dreaded goto command?
crazyhorseavi
2008-02-28 09:30:31 UTC
Everyone tells me that the goto command should always be avoided. It seems to have a very bad reputation these days. But is it really that bad?

Here is my specific question: Suppose you have a program with various functions that call one another, all in the usual way. Suppose now, you label each one, and replace all the function calls with goto statements. (Imagine that in the situation I'm describing you will never need to return to a function that you have left until you call it again.) Would this be in any way worse than calling the function the standard way? I can imagine that, depending on the logic of your program, there are times that it might be better. As long as you are not breaking into anything that might get complicated, like a loop, what is the problem with goto, if any?
Eight answers:
2008-02-28 09:36:51 UTC
Of course it would be worse... when you call a function, the code has to save the state of the previous functions in the registers, set up stack frames... all of which would be avoided if you used a goto to jump into a function. You would end up with undefined behavoir all over the place and I'm not even sure if the standard would allow it.



There is absolutely no advantage to using a goto other than occasionally convenience. It's taught to be avoided to students because they use them wrong. When you are experienced and you know how to use them properly, you may... however, you will rarely need to.



EDIT (to your response): You can't ignore saving the registers... if you don't the new function will attempt to overwrite the registers of the old function. The data needs to be placed in memory. You also can't avoid setting up the stack frames because it could cause you to overload your buffer just like a bad recursive function would. Jumping out of a function causes as much undefined behavior as jumping into the middle of a for loop... you just can't expect the right thing to happen.



Any proper compiler will optimize your code to the extent that any function that *might* get an immediate performance increase from a function would just get inlined into the program by the optimizer, anyway. So in the end, you'd not be gaining anything if you could gain something in the first place.
2008-02-28 17:42:43 UTC
Ok,



the fair problem with GOTO loop is that it can cuase a lock up in your program, and cuase an infinite loop. They should be avoided, just use pure function calls as a replacement.



in your situation i would just stick with the function calls, avoid using GOTO as much as possible unless you need to extract data from the client, and the client is not providing you with the correct form that you want.





For example this BASIC Program using GOTO:



get_answer:

dim get_math as integer

get_math = inputbox("what is 2+2?","Math problem...")

if get_math = 4 then

msgbox "Math Problem" & vbnewline & _

"Congratulations :-)",vbinformation + vbokonly,"Awesome."

end if



if get_math < 4 OR > 4 then

goto get_answer

end if





ok so you know that using that form of goto is about the only safe method possible. However, lets examine an situation where goto would be unsafe.





A:

echo hello.

goto A:



in a batch program, this would case an infinite loop and process unlimited hello output messages to the command window slowing down user performance and possibly crashing the operating system (* depending on the hardware *)





that is why we programmers try to avoid goto as much as possible and use function calls as much as we can.



Hope i was of any help.
BalRog
2008-02-28 18:18:34 UTC
I refer you to David Tribble's recent (2005) annotated retrospective of E. W. Dijkstra's famous 1968 letter to the ACM entitled "Go To Statement Considered Harmful". I strongly recommend that you read it in its entirety. It puts the whole issue in historical context. It avoids dogma on either side of the debate. And it comes to a rational. balanced conclusion about the whole issue.



Personally, my first heavily-used programming language was Fortran IV, in which a great majority of the code DEPENDS on the use of the "GOTO statement". Enormous amounts of my team's time and effort went into debugging spaghetti code.



As Fortran 77 and C began to dominate the landscape, the situation improved a great deal. Fairly often I was able to resolve longstanding bugs in Fortran IV code simply by rewriting it to use structured loops and conditionals. In many of those cases the bug became obvious merely by going through the thought process of converting goto-laden logic to structured logic. The conclusion to me was that structured logic just fits the human brain better than jump-and-branch logic.



Which brings us to now. For the past 10 years I have worked almost exclusively in Java, which has no goto construct whatsoever. I do not miss it at all.



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

As to your specific question, my return question is "why?" Function names document usage and, well used, can make the purpose of a code block crystal clear. Goto labels can document usage, but inputs and outputs of a code goto code block are a mystery.



Sure, you can do it. And you could even rig up a stack mechanism of your own so that you can remove your "never need to return" proviso. But why oh why would you want to?



"Would this be in any way worse..."? Yes, code readability would suffer considerably.



"...there are times it might be better." Can you give us an example? I can think of examples where it might be "not so bad", but none where it is "better".



"As long as you are not breaking into anything that might get complicated..." Well, back in the day that was exactly the problem. People used goto statements to do all sorts of complicated overlapping-but-not-nested looping/skipping constructs. However, in fairly simple cases, spread over no more than a few lines, you could get some fairly elegant looking (though still hard to decipher) code. For example, there is this from the paper I referenced:



int parse()

{

Token tok;



reading:

tok = gettoken();

if (tok == END) return ACCEPT;

shifting:

if (shift(tok)) goto reading;

reducing:

if (reduce(tok)) goto shifting;

return ERROR;

}



I still like the following structured equivalent better, because it makes the nature of the looping a lot more obvious:



int parse()

{

Token tok;



while (true) {

tok = gettoken();

if (tok == END) return ACCEPT;



while (true) {

if (shift(tok)) break;



if (!reduced(tok)) return ERROR;

}

}

}



But the overall code is small and simple enough that I would not really be bothered by the unstructured code block.



In my experience, though, REAL goto-laden code is almost never that short and elegant. The label is usually somewhere between dozens and hundreds of lines from the goto and there is no easy way to tell which direction to go just by looking at the goto. Perhaps if there were two different statements: goback and goforward, it would not be as bad, but, alas, in real languages there aren't.
skumpfsklub
2008-02-28 18:43:12 UTC
Disciplined use of the goto isn't a bad thing. You might shave a few operating cycles here and there, that could amount to considerable time-saving.



The question you outline shows a disciplined approach, so go for it. See if the box makes smoke. If it doesn't, you're okay. The 'problem of the goto' is that it's been too often used recklessly, with disastrous results.



It's risky business from a maintenance perspective, for reasons of difference between humans, i.e., the author(s) of the program, and the maintenance programmer(s). Strict use of calls tends to reduce the importance of that, facilitates parcelling the work out, as over time or as comes available manpower. But I stress that this is 'human factors' consideration; the machine doesn't care about the aesthetics of the code, nor about the technical catfights in the coffee room.
The Phlebob
2008-02-28 17:42:13 UTC
The problem with a goto is that it's too easy to misuse. Early code often jumped to various places in open subroutines, with all good intentions of setting all the needed entry variables. Later, when another entry variable was added, but the code wasn't updated -- because everyone forgot about one more goto (this was before decent Find tools, by the way) -- the code suddenly broke.



Second, Gotos tend to produce "spaghetti code," where drawing lines from the Goto's to their targets produces tangled lines like a bowl of spaghetti. They can be impossible to completely understand.



I haven't used a goto in at least twenty years. In fact, I haven't felt the need to.



Hope that helps.
2008-02-28 17:39:06 UTC
I use goto for exception handling, and that's it. I think that is the only purpose it could possibly serve. Calling the functions or subs just seems to work so much smoother, but I guess if your app is running...the only problem is explaining it to any successive programmers who wonder why the heck you broke conventions.



Like I said though...if the app runs smoothly, more power to ya. But when you script something more complicated, I'd avoid using GoTo to call functions or subs.



Proper calling should be a round trip ticket...GoTo is a one way, which is why it is pretty much only useful for exception handlers.
Tasm
2008-02-28 17:53:16 UTC
To call function xyz, just need to type zyx with the parameters so why put goto xyz?



var test;

test = sum(10,20);



This would be a waste

test = goto sum(10,20);



The goto is just pointless.
Robert S
2008-02-28 17:38:26 UTC
In one word -- MAINTENANCE. Following the resulting spaghetti code and knowing what has been set and where you're returning to is hell. Take from one who has been programming when goto was considered normal.


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...