goto is almost universally discouraged. Is using this statement ever worthwhile?

  • 17
    xkcd.com/292 – TheLQ Sep 2 '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. – user1249 Feb 6 '12 at 9: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 6 '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. – user1249 Feb 6 '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 6 '12 at 10:30

12 Answers 12


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.

  • 30
    The 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 2 '10 at 22:03
  • 2
    Very good points. I like how Java allows breaking out of multiple levels of loops – Casebash Sep 2 '10 at 23:08
  • 4
    @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 8 '10 at 17:54
  • 24
    Okay 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 3 '11 at 3:20
  • 4
    About 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 6 '12 at 12:01

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.

  1. Breaking out of a nested loop. This would be unnecessary if the language had a labeled break statement.
  2. 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.
  3. 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.

  • 7
    This is actually the best answer so far – rather surprising, for a question that is one and a half years old. :-) – Konrad Rudolph Feb 6 '12 at 16:45
  • 1
    +1 to "best answer so far". --- "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." – Dave Dopson Jun 25 '12 at 16:20
  • In switch-statement state machine, every write to the control value is really a goto. SSSM's are often good structures to use, since they separate out the SM state from the execution construct, but they don't really eliminate "gotos". – supercat Feb 14 '14 at 21:59
  • 2
    "All else being equal, code whose structure reflects that of the problem domain tends to be easier to read and maintain." I've known this completely for a long time but lacked the words to so precisely communicate it in a way that other programmers can and will actually understand. Thank you for this. – Wildcard Aug 26 '16 at 2:55
  • 1
    The "structured program theorem" amuses me, since it tends to clearly demonstrate the point that using structured programming statements to emulate a goto is much less readable than just using a goto! – user122173 Aug 27 '16 at 13:48

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.

  • 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
    goto 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
  • 8
    And 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
  • 4
    @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 6 '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 4:17
  • 1
    @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

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.

  • 3
    "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 6 '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 6 '12 at 12:37

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
    The 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.

  • 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 gotos 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 6 '12 at 16:48
  • (Alas, most languages forbid jumping into a loop.) – Konrad Rudolph Feb 6 '12 at 16:56
  • @KonradRudolph: If you implement the "loop" with GOTO there is no other loop structure to be jumping into. – Loren Pechtel Feb 7 '12 at 19:34
  • 2
    I 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.)


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.


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.

  • Correct, but one of the arguments against gotos 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

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.

  • I'd argue that when languages have both these features, goto is typically absent from those languages. – Chinmay Kanchi Sep 2 '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 4 '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 6 '12 at 8:56
  • 1
    @SK-logic: I don't think the word "bigoted" means what you think it means. – Keith Thompson Feb 6 '12 at 9: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 6 '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.

  • 4
    Maybe, but you haven't provided any reasoning – Casebash Sep 2 '10 at 23:09
  • Dijkstra provided the reasoning, in detail, decades ago. – John R. Strohm Dec 18 '11 at 15:04
  • 3
    Just 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 6 '12 at 8: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

Not the answer you're looking for? Browse other questions tagged or ask your own question.