goto
is almost universally discouraged. Is using this statement ever worthwhile?
-
18http://xkcd.com/292/ – TheLQ Sep 02 '10 at 23:25
-
1`goto` is what the cpu ultimately do, but it does not work well with what humans need to comprehend and abstract due to there is no mark on the target end. Compare to Intercal `COMEFROM`. – Feb 06 '12 at 09:57
-
2@ThorbjørnRavnAndersen, what else humans mean when they're talking about *state transitions* in a state machine? Can't you see a similarity? "Go to a given *state*", that's what it means and anything else would be nothing but an unnecessary complication of such a trivial thing. And what do you mean by "no mark"? Label is such a mark. – SK-logic Feb 06 '12 at 10:10
-
@SK-logic, depends on how far away you will allow goto's to come from. State machines do not require goto to implement. – Feb 06 '12 at 10:26
-
@ThorbjørnRavnAndersen, of course `goto` is not required. It is just the most rational way of implementing them in the imperative languages, since it is the closest thing to the very semantics of the state transition. And its destination can be quite far from the source, it won't hinder the readability. My favourite example of such a code is D.E. Knuth's implementation of the Adventure game. – SK-logic Feb 06 '12 at 10:30
-
@TheLQ, **obligatory:** xkcd author is a math guy, not a code guy. I'd not think he even wrote a line of code? – Pacerier May 23 '17 at 07:53
-
@user1249, That's ur limitation, not of {others, all}. [Also see this](http://www.paulgraham.com/avg.html). Humans comprehend the way they are {taught, used} to. – Pacerier May 23 '17 at 07:54
14 Answers
Higher-level control flow constructs tend to correspond to concepts in the problem domain. An if/else is a decision based on some condition. A loop says to perform some action repeatedly. Even a break statement says "we were doing this repeatedly, but now we need to stop".
A goto statement, on the other hand, tends to correspond to a concept in the running program, not in the problem domain. It says to continue execution at a specified point in the program. Someone reading the code has to infer what that means with respect to the problem domain.
Of course all the higher-level constructs can be defined in terms of gotos and simple conditional branches. That doesn't mean that they're merely gotos in disguise. Think of them as restricted gotos -- and it's the restrictions that make them useful. A break statement is implemented as a jump to the end of the enclosing loop, but it's better thought of as operating on the loop as a whole.
All else being equal, code whose structure reflects that of the problem domain tends to be easier to read and maintain.
There are no cases where a goto statement is absolutely required (there's a theorem to that effect), but there are cases where it can be the least bad solution. Those cases vary from language to language, depending on what higher-level constructs the language supports.
In C, for example, I believe there are three basic scenarios where a goto is appropriate.
- Breaking out of a nested loop. This would be unnecessary if the language had a labeled break statement.
- Bailing out of a stretch of code (typically a function body) in case of an error or other unexpected event. This would be unnecessary if the language had exceptions.
- Implementing an explicit finite state machine. In this case (and, I think, only in this case) a goto corresponds directly to a concept in the problem domain, transitioning from one state to a specified other state, where the current state is represented by which block of code is currently executing.
On the other hand, an explicit finite state machine can also be implemented with a switch statement inside a loop. This has the advantage that every state starts at the same place in the code, which can be useful for debugging, for example.
The main use of a goto in a reasonably modern language (one that supports if/else and loops) is to simulate a control flow construct that's missing from the language.

- 6,402
- 2
- 29
- 35
This has been discussed several times on Stack Overflow, and Chris Gillum summarized the possible uses of goto
:
Cleanly exiting a function
Often in a function, you may allocate resources and need to exit in multiple places. Programmers can simplify their code by putting the resource cleanup code at the end of the function all all "exit points" of the function would goto the cleanup label. This way, you don't have to write cleanup code at every "exit point" of the function.
Exiting nested loops
If you're in a nested loop and need to break out of all loops, a goto can make this much cleaner and simpler than break statements and if-checks.
Low-level performance improvements
This is only valid in perf-critical code, but goto statements execute very quickly and can give you a boost when moving through a function. This is a double-edged sword, however, because a compiler typically cannot optimize code that contains gotos.
I'd argue, as many others would argue, that in all of these cases, the usage of goto
is used as a means to get out of a corner one coded oneself into, and is generally a symptom of code that could be refactored.
-
36The first problem is solved very neatly by `finally` blocks in modern languages, and the second is solved by labelled `break` s. If you're stuck with C however, `goto` is pretty much the only way of solving these problems elegantly. – Chinmay Kanchi Sep 02 '10 at 22:03
-
2Very good points. I like how Java allows breaking out of multiple levels of loops – Casebash Sep 02 '10 at 23:08
-
-
7@Chinmay - finally blocks only apply to 1) modern languages that have them and b) you can tolerate the overhead (exception handling does have an overhead.) That is, using `finally` is only valid under those conditions. There are very rare, yet valid situations where a goto is the way to go. – luis.espinal Nov 08 '10 at 17:54
-
@luis: I don't disagree at all. There are places where `goto` is simply the best way to solve a problem... – Chinmay Kanchi Nov 08 '10 at 19:12
-
26Okay people... what the heck is the difference between `break 3` or `break myLabel` and `goto myLabel`. Oh that's right just the keyword. If you are using `break`, `continue` or some similar keyword you are infact using a `goto` (If you are using `for, while, foreach, do/loop` you are using a conditional goto.) – Matthew Whited Jan 03 '11 at 03:20
-
2@Matthew: A labelled `break` only allows you to jump to the statement _immediately following the labelled loop_, not any arbitrary point in code. Yes, it is only syntactic sugar for a `goto`, but it makes it immeasurably safer to use. – Chinmay Kanchi Feb 04 '11 at 01:48
-
1That totally depends on the language. There are similar rules that follow goto in languages such as C#. – Matthew Whited Feb 04 '11 at 04:33
-
5About low level performance - the behaviour of modern processor might be hard to predict (pipeline, out-of-order execution) so probably in 99% of cases it is not worth it or even it might be slower. @MatthewWhited: Scoping. If you enter scope at arbitrary point it is not clear (to human) what constructors should be called (the problem exists in C as well). – Maciej Piechotka Feb 06 '12 at 12:01
-
@ChinmayKanchi Matt is not talking about all possibilities of the `goto` statement. He is talking about a situation where `break 3` would be applicable but the language does not have it. But has `goto`. In *that* case `goto` is just as elegant or bad as `break 3`. – Notinlist Sep 26 '12 at 12:35
-
@MatthewWhited: "If you are using [loop construct] you are using a conditional goto". Umm, not necessarily. I can implement all those at the assembly level without a use of goto or something built from JUMP (goto); it just would not be efficient. Here's how: instead of jumping, write NOP statements over the code you would jump over. In the place where you would jump to, write back the original contents. Abstractions ≠ implementations! – Thomas Eding Oct 24 '12 at 21:16
-
-
What I described as an alternative requires no jump/goto. It requires writing over memory and normal IP increments. – Thomas Eding Oct 24 '12 at 23:30
-
@ThomasEding Are you really suggesting that using self-modifying code is a better alternative than using a goto? If you're just being clever, I'll also point out that you are wrong on any Harvard architecture (which includes almost all embedded processors) where the instruction space isn't writable or even necessarily addressable. – wjl Jun 27 '14 at 11:12
-
@wjl All I'm saying is that loops do not necessarily need to be implemented with goto logic. That's the fallacy. Practicality is an orthogonal issue. Saying such an implementation can't work on said machine is irrelevant because another machine may theoretically support it. – Thomas Eding Jun 27 '14 at 16:54
-
2Goto, as a concept, is inevitable. Giving it nice names and restricting where it can (safely) jump, it helps a lot. All those words like break, continue, catch, finally - those are glorified goto statements. Whenever you can go with them, go with them. It's safer. On the other hand, safety should be optional. Restricting programmers JUST for the sake of safety - like "don't ever cross the road because some died like that" - it's a debatable topic. I would say let's not. – dkellner Sep 27 '19 at 09:17
-
1“Compilers cannot optimise goto” - I had some _very_ performance critical code with in inner loop that was executed once except one in a billion time where it ran twice. The compiler moved operations from inside the loop to the outside which was inefficient because there was practically never more than one iteration. I tried rewriting it with goto so the compiler wouldn’t “optimise” the loop but couldn’t stop it. – gnasher729 Jul 06 '21 at 23:53
The most of the discouragement comes form a sort of "religion" that has been created aroud God Djikstra that was compelling in the early '60s about it's indiscriminate power to:
- jump anywhere into whatever block of code
- function not executed from the begining
- loops not executed from the beginning
- skipped variable initialization
- jump away from whatever block of code without any possible cleanup.
This has nothing more to do with the goto
statement of the modern languages, whose existence is merely due to support the creation of code structures other than the language provided ones.
In particular the first main point above is anymore permitted and the second is cleaned (if you goto
out of a block the stack is unwinded properly and all proper destructors called)
You can refer this answer to have an idea of how even code not using goto can be unreadable. The problem is not goto itself, but the bad use of it.
I can write an entire program without using if
, just for
.
Of course, it will not be well readable, an look clumsy and unnecessarily complicated.
But the problem is not for
. It's me.
Things like break
, continue
, throw
, bool needed=true; while(needed) {...}
, etc. are noting more than masquerade goto
to escape away from the scimitars of the Djikstrarian zealots, that -50 years after the invention of modern laguages- still want their prisoners. They forgot what Djikstra was talking about, they only remember the title of his note (GOTO considered harmful, and it was not even his onw title: it was changed by the editor) and blame and bash, bash and blame every contruct having those 4 letter placed in sequence.
It's 2011: it's time to understand that goto
has noting to deal with the GOTO
statement Djikstra was compelling about.

- 4,289
- 1
- 22
- 23
-
4"Things like break, continue, throw, bool needed=true; while(needed) {...}, etc. are noting more than masquerade goto" I don't agree with that. I would prefer "things like break etc are _restricted_ goto", or something like that. The main problem with goto is that it is usually too powerful. To the extent that the current goto is less powerful than Dijkstra's, your answer is fine with me. – Muhammad Alkarouri Feb 06 '12 at 12:20
-
3@MuhammadAlkarouri: I totally agree. You just found a better wording to express exactly my concept. My point is that those restriction can sometimes not be applicable and the kind of restriction you need is not in the language. Then a more "powerful" thing, less specialized, is what makes you able to workaround. For example, the Java `break n` is not available in C++, hence `goto escape`, even if `escape` is not required to be just out from the n-ple loop. – Emilio Garavaglia Feb 06 '12 at 12:37
Surely it depends on the programming language. The main reason goto
has been controversial is because of its ill effects that arise when the compiler lets you use it too liberally. Problems can arise, for example, if it lets you use goto
in such a way that you can now access an uninitialised variable, or worse, to jump into another method and mess with the call stack. It should be the responsibility of the compiler to disallow nonsensical control flow.
Java has attempted to “solve” this problem by disallowing goto
entirely. However, Java lets you use return
inside a finally
block and thus cause an exception to be inadvertantly swallowed. The same problem is still there: the compiler is not doing its job. Removing goto
from the language hasn’t fixed it.
In C#, goto
is as safe as break
, continue
, try/catch/finally
and return
. It doesn’t let you use uninitialised variables, it doesn’t let you jump out of a finally block, etc. The compiler will complain. This is because it solves the real problem, which is like I said nonsensical control flow. goto
doesn’t magically cancel definite-assignment analysis and other reasonable compiler checks.

- 4,411
- 29
- 37
-
Your point is that C#'s `goto` is not evil? If so, that is the case for every routinely used modern language with a `goto` construct, not only C#... – lvella Jun 30 '15 at 17:42
Yes. When your loops are nested several levels deep, goto
is the only way of elegantly breaking out of an inner loop. The other option is to set a flag and break out of each loop if that flag satisfies a condition. This is really ugly, and pretty error-prone. In these cases, goto
is simply better.
Of course, Java's labelled break
statement does the same thing, but without allowing you to jump to an arbitrary point in the code, which solves the problem neatly without allowing the things that make goto
evil.

- 6,173
- 2
- 39
- 51
-
Anyone care to explain the downvote? This was a perfectly valid answer to the question... – Chinmay Kanchi Sep 03 '10 at 00:19
-
6goto is never an elegant answer. When your loops are nested several levels deep, your problem is that you failed to architect your code to avoid the multinested loops. Procedure calls are NOT the enemy. (Read the "Lambda: The Ultimate ..." papers.) Using a goto to break out of loops nested several levels deep is putting a band-aid on an open multiple fracture: it may be simple but it isn't the right answer. – John R. Strohm Dec 18 '11 at 15:03
-
10And of course, there is never the odd case when deeply nested loops are called for? Being a good programmer isn't just about following the rules, but also about knowing when to break them. – Chinmay Kanchi Dec 27 '11 at 13:53
-
5@JohnR.Strohm Never say never. If you use terms like "never" in programming , you've clearly not dealt with corner cases, optimization, resource contraints, etc. In deeply nested loops, *goto* is very much indeed the most cleanest, elegant way to exit the loops. Doesn't matter how much you've refactored your code. – Sujay Phadke Feb 06 '16 at 21:34
-
1@JohnR.Strohm: Second most missed feature on switching from VB.NET to C#: the `Do` loop. Why? Because I can change the one loop that needs a deep break into a `Do` loop and type `Exit Do` and there's no `GoTo`. Nested loops happen all the time. Breaking the stacks happens some % of the time. – Joshua Jan 22 '19 at 04:17
-
2@JohnR.Strohm The only reason why you say "goto is never an elegant answer" is because you made your mind up that goto is never an elegant answer, and therefore any solution using goto cannot be an elegant answer. – gnasher729 May 19 '20 at 21:58
-
When you have control structures multiple levels deep, refactor your code. This is a major code smell. And it is easily avoidable and will make your code so much easier to read. A goto may sometimes be an OK solution to leaving a loop and I have done it many times when hacking something fast but it is a sign you're probably doing it wrong. That being said there are valid usages of goto in plain C. – Gellweiler Jan 06 '21 at 21:05
The odd goto here or there, so long as it's local to a function, rarely significantly harms readability. It often benefits it by drawing attention to the fact that there's something unusual going on in this code that requires the use of a somewhat uncommon control structure.
If (local) gotos are significantly harming readability, then it's usually a sign that the function containing the goto has become too complex.
The last goto I put into a piece of C code was to build a pair of interlocking loops. It doesn't fit into the normal definition of "acceptable" goto use, but the function ended up significantly smaller and clearer as a result. To avoid the goto would have required a particularly messy violation of DRY.

- 1,133
- 7
- 8
-
1The answer to this is most pithily stated in the old "Lay's Potato Chips" slogan: "Bet you can't eat just one". In your example, you have two "interlocking" (whatever that means, and I'm betting it isn't pretty) loops, and the goto gave you a cheap out. What about the maintenance guy, who has to modify that code after you got hit by a bus? Is the goto going to make his life easier or harder? Do those two loops need rethinking? – John R. Strohm Dec 18 '11 at 15:09
I think this whole issue has been a case of barking up the wrong tree.
GOTO as such doesn't seem problematic to me, but rather it's very often a symptom of an actual sin: spaghetti code.
If the GOTO causes major crossing of flow control lines then it's bad, period. If it crosses no flow control lines it's harmless. In the grey zone in between we have things like loop bailouts, there are still some languages that haven't added constructs that cover all the legit grey cases.
The only case I've found myself actually using it in many years is the case of the loop where the decision point is in the middle of the loop. You're left with either duplicated code, a flag or a GOTO. I find the GOTO solution the best of the three. There is no crossing of flow control lines here, it's harmless.

- 3,371
- 24
- 19
-
The case you allude to is sometimes dubbed “loop and a half” or “N plus one half loop” and it’ a famous use-case for `goto`s that jump into a loop (if the language allows this; since the other case, jumping out of the loop in the middle, is usually trivial without `goto`). – Konrad Rudolph Feb 06 '12 at 16:48
-
-
@KonradRudolph: If you implement the "loop" with GOTO there is no other loop structure to be jumping into. – Loren Pechtel Feb 07 '12 at 19:34
-
2I think of `goto` as shouting **THE CONTROL FLOW HERE DOESN'T FIT NORMAL STRUCTURED-PROGRAMMING PATTERNS**. Because control flows which fit structured programming patterns are easier to reason about than those which don't, one should attempt to use such patterns when possible; if code does fit such patterns, one shouldn't shout that it doesn't. On the other hand, in cases where code really doesn't fit such patterns, shouting about it may be better than pretending the code fits when it really doesn't. – supercat Mar 27 '14 at 17:23
-
1@supercat Well, imagine you wrote yourself a schedule, and then the wind blows it out of your hands. According to your logic, you shouldn't retrieve it, because chasing after your schedule wasn't on your schedule. – Sapphire_Brick May 19 '20 at 20:53
Yes, the goto can be used to benefit the experience of the developer: http://adamjonrichardson.com/2012/02/06/long-live-the-goto-statement/
However, just as with any powerful tool (pointers, multiple inheritance, etc.), one has to be disciplined using it. The example provided in the link uses PHP, which restricts the usage of the goto construct to the same function/method and disables the ability to jump into a new control block (e.g., loop, switch statement, etc.)

- 131
- 2
Depends on the language. It's still widely used in Cobol programming, for example. I've also worked on a Barionet 50 device, whose firmware programming language is an early BASIC dialect that of course requires you to use Goto.

- 3,583
- 1
- 25
- 22
It has been mentioned that it's good for exiting nested loops and for cleanups. But I have a case which doesn't fit (at least not perfectly) in any of those cases, even though it's inspired by both. And it also involves the philosophy of single return.
void foo(void *ptr) {
if(!ptr) goto END;
while( <condition1> ) {
// Code
if( <condition2> ) goto END;
// Code
}
END:
printf("Exiting");
}
In this case, you could use a break
in the loop instead. But why? The goto
gives more information. A if(condition) break
says that we should exit the loop. A if(condition) goto END
instead says that we should go to the end of the function and do the remaining part. To me it's clearer.

- 1,428
- 1
- 10
- 25
-
I don't see that the goto "gives more information" in these cases. The first jump can be incorporated into an if-block, and the second jump can be converted into a break (if not elided completely by moving the break condition into the while-block condition). And although the label makes the jump target unambiguous, structured blocks are similarly unambiguous. Anyway the risks with gotos do not emerge in such simple examples as these, but only when they form a weave (and thus the order of operations, and the number of paths, becomes increasingly difficult to see). – Steve Jul 07 '21 at 06:33
-
@Steve I do not condone weaves of goto. That's where the problem arises. – klutt Jul 07 '21 at 07:12
-
What's still not clear is why you would use goto at all, when the simple cases (like yours) are so easily replaced by purely structured blocks? The diktat against gotos, after all, is because they violate the regularity of structured blocks. Neither of your blocks, once entered, actually exit in accordance with the block principle (that is, the execution of a given block is followed by the execution of the first line after the given block). – Steve Jul 07 '21 at 09:23
-
*And it also involves the philosophy of single return* That's the real problem: force-fitting a square algorithm that is simply implemented with multiple return statements into the round hole of "every function may have only one return". "Must cram all algorithms into this one pattern"? Even if they don't fit? You have to make the code more complex just to force-fit it into a rule that's supposedly for making code easier to understand and more maintainable? – Andrew Henle Jul 07 '21 at 10:50
-
@AndrewHenle In this case, it's because I want to run the print statement upon exiting. – klutt Jul 07 '21 at 10:55
-
so adding a break statement into the loop definitely makes it worse, adding an if check into the loop also makes it worse. Some languages like python support a null return for void methods. So the code could say `if (!ptr) { print("Exiting"); return;` and that seems even more direct than jumping with the GOTO. Now if theres a bunch of context required to exit, you could write a helper method `void Returner(arg1 ag2 ...)` and then your code is `if (!ptr) { return Returner(ptr, ...) }`. If you have a TON of context this still sucks, since you might have a 10+ argument method call. – Sidharth Ghoshal Jul 19 '22 at 14:21
-
I guess in that last edge case a goto might just be justified – Sidharth Ghoshal Jul 19 '22 at 14:21
goto
may be useful when porting legacy assembler code to C. In the first instance, an instruction-by-instruction conversion to C, using goto
as a replacement for the assembler's branch
instruction, can enable very rapid porting.

- 809
- 6
- 7
-
Correct, but one of the arguments against `goto`s is that they thwart compiler optimizations. – Sapphire_Brick May 19 '20 at 20:46
-
@Sapphire_Brick: Many compiler optimizations are designed around certain execution patterns. If the task to be performed doesn't fit the supported execution patterns, "thwarting" optimizations may not be a bad thing. – supercat May 19 '20 at 22:48
As an example how moaning about goto can be pointless: I had some lengthy code that asked for gotos in many places jumping past the end of that chunk of code. Unfortunately this was C++. And C++ doesn’t let you goto past any variable initialisation.
Do - while came to the rescue:
do {
…
If (condition) break;
…
If (condition2) break;
…
} while (0);
Completely equivalent to using gotos instead of break statements.

- 42,090
- 4
- 59
- 119
-
You can skip variable initialization in C++; you just have to skip the entire scope containing that variable. The goto-equivalent could work if you put the code in question in a block. – Nicol Bolas Jul 08 '21 at 23:07
-
It would seem that what is really missing from structured languages, is the existence of a block (with a specific keyword) whose only purpose for being declared is to allow a jump to its exit point. – Steve Jul 09 '21 at 10:26
I would argue no. They should always be replaced with a tool more specific to the problem the goto is being used to solve (unless it's not available in your language). For example, break statements and exceptions solve to previously goto-solved problems of loop escaping and error handling.

- 25,909
- 15
- 111
- 154
-
I'd argue that when languages have _both_ these features, `goto` is typically absent from those languages. – Chinmay Kanchi Sep 02 '10 at 22:45
-
But is that because they don't need them, or because *people* think they don't need them? – Michael K Nov 04 '10 at 12:46
-
Your views are bigoted. There are many cases when `goto` is the closest thing to the very problem domain semantics, anything else would be a dirty hack. – SK-logic Feb 06 '12 at 08:56
-
1@SK-logic: I don't think the word "bigoted" means what you think it means. – Keith Thompson Feb 06 '12 at 09:51
-
1@Keith, "intolerantly devoted to his or her own opinions and prejudices" - that's what I consistently observe here, with this goto-bashing blindfolded lot. "Should *always* be replaced" are fanatic's words, at least. Nothing close to a proper, sound opinion, but just a pure bigotry. This "always" does not leave any space for any alternative opinion, see? – SK-logic Feb 06 '12 at 10:06
-
I would say no. If you find the need for using GOTO, I'll bet that there's a need to redesign the code.

- 16,158
- 8
- 58
- 95
-
4
-
-
4Just Dogma. No resons. Note: Djikstra is NOT ANYMORE A VALID RESON: it was referring of the BASIC or FORTRAN GOTO statement ofn the early '60s. They have nothing to do with the really anemic (compared to the power of those) gots-s of today. – Emilio Garavaglia Feb 06 '12 at 08:54
-
@EmilioGaravaglia Well, the part of his reasoning that still applies today is that it's very easy to write spaghetti code by using way to many gotos. However, by that logic, we shouldn't use pointers because using as many pointers as `number of gotos needed to create problems` would create similar chaos. – Sapphire_Brick May 19 '20 at 20:42