227

Possible Duplicates:
Why is it bad to use goto?
GOTO still considered harmful?

I was ramdomming through xkcd and saw this one (if also read some negative texts about them some years ago):
your slow connection sucks, get a faster one to see this image
What is actually wrong with it? Why are goto's even possible in C++ then?

Why should I not use them?

Community
  • 1
  • 1
  • 61
    I don't see anything wrong with the question. So +1 to counteract downvotes. – NullUserException Aug 19 '10 at 00:13
  • 2
    This blog on the topic is worth a read: http://blog.smartbear.com/development/goto-still-has-a-place-in-modern-programming-no-really/ – JamieSee Nov 01 '16 at 18:15
  • 11
    The best reason to avoid GOTO is exemplified by the xkcd cartoon: if you use GOTO, you're likely to be attacked by a dinosaur. – PedanticDan Nov 29 '19 at 22:31
  • [The answer](https://stackoverflow.com/a/46789/465053) with same graphic on another post. – RBT Dec 02 '19 at 23:56
  • 1
    Check out Dijkstra's original [Go to statement considered harmful](http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html). But don't forget Knuth's [Structured programming with goto statements](https://dl.acm.org/doi/10.1145/356635.356640) which explains why you might use them and how they can fit with rather than oppose the goals of structured programming – Riley May 05 '22 at 19:10

6 Answers6

169

Because they lead to spaghetti code.

In the past, programming languages didn't have while loops, if statements, etc., and programmers used goto to make up the logic of their programs. It lead to an unmaintainable mess.

That's why the CS gods created methods, conditionals and loops. Structured programming was a revolution at the time.

gotos are appropriate in a few places, such as for jumping out of nested loops.

stateMachine
  • 5,227
  • 4
  • 13
  • 29
Byron Whitlock
  • 52,691
  • 28
  • 123
  • 168
  • 32
    Jumping out of nested loops are the *only* instance I have used goto statements. Even then, I refactor my code to simply return early when possible. – Charlie Salts Aug 19 '10 at 00:14
  • 131
    +1 for acknowledging that `goto` still has a purpose on rare occasions. – Matt Davis Aug 19 '10 at 01:25
  • 1
    I remember reading gotos are often used by some tools that auto-generate code, like parser generators etc. – neuviemeporte Jan 14 '15 at 14:27
  • 3
    I know this is an old post, but I thought I'd add one more use for goto. In SQR goto is commonly used as a 'continue' in a loop. Many database languages don't have continues in the language so they put a goto at the end of the loop and call it if they need to 'continue'. – brw59 Jun 19 '16 at 03:40
  • 2
    More accurate to say because they *can* easily lead to spaghetti code if not used wisely. Sometimes it is actually the cleanest, DRYest way of doing things, especially in languages that don't focus on structured programming, as I've just discovered when trying to make a loop continue in T-SQL. – Denziloe Feb 19 '19 at 16:35
  • 6
    A `return` can be used instead of `goto` to jump out of nested loops. For example, extract the nested loops into a new function and return from there when the condition that triggers the `goto` is satisfied. I only see `goto` being used only to get an extra bit of performance – mljrg Oct 04 '19 at 09:57
  • 1
    "In the past, programming languages didn't have .... if statements" err. Basic always had if statements... as did most assembly languages. (although "if" might be "jump if zero") As for using goto in nested loops; personally I'd argue that if you want to jump out a nested loop; then you make a function and return from it. – UKMonkey Oct 06 '19 at 17:08
  • 1
    @mljrg That create a new function thing often isn't a good solution when your current function has a bunch of context with it that you'd have to pass around. Also, what if you have nested loops and conditions and you don't want to jump all the way out? Once you go beyond basic code this sort of scenario definitely happens here and there and goto is a very clean, easy, readable solution. – Andrew Jun 15 '21 at 07:41
  • @Andrew The important thing is that at the end the code should be as much understandable as possible, whether using a `goto` or not. The best solution will depend on a case basis, but I still have to see a `goto` proving to be the best understandable solution. Perhaps this is because I mostly use only functional programming. – mljrg Jun 24 '21 at 16:47
  • @Andrew Beware that a function with a bunch of context is perhaps doing to much, and a candidate to be broken into simpler functions, thus making the final code more understandable. Again, I suppose there will be exceptional cases ... but very frequently in C programs I see enormous functions that can scare anyone a lot. I wonder how many bugs are hidden there ;-) – mljrg Jun 24 '21 at 16:51
  • @mljrg I gave you the instances in which `goto` is the best solution: nested loops and conditions. Try looping through multiple dimensions, or looping through a bunch of trees or linked lists simultaneously. Video game and graphing applications come to mind, where you have lots of structured data loading, graphics, stitching data together and apart, etc. In some situations, where you are exactly in an algorithm's "steps" can be several pieces of context in and of itself. Splitting your code up into many small functions is a bad idea, because then you're looping over many call stack operations. – Andrew Jun 26 '21 at 21:47
  • @Andrew A good compiler would let it be instructed to inline the function calls as appropriate to avoid a negative performance impact inside nested loops, while retaining the greater understandability of having smaller focused functions. If you are in C++ you can throw an exception to do a non-local return from deep inside several nested function calls, and likewise, it can be done in C using `setjmp` and `longjmp` (see [here](https://stackoverflow.com/questions/14685406/practical-usage-of-setjmp-and-longjmp-in-c)). But for a typical few cases I admit that a `goto` may be the best option. – mljrg Jun 28 '21 at 18:41
  • @mljrg That's true until you factor in the context you have to pass around and return in order to replace the `goto` functionality, and then it's not going to get optimized. Both of your other examples are slow, and exceptions are not made for this purpose. – Andrew Jun 30 '21 at 22:09
  • JavaScript lets you `break` out of labelled loops, which I've found useful. – Cloud Aug 29 '22 at 04:13
107

Nothing is wrong with goto if it is used properly. The reason it is "taboo" is because in the early days of C, programmers (often coming from an assembly background) would use goto to create incredibly hard-to-understand code.

Most of the time, you can live without goto and be fine. There are a few instances, however, where goto can be useful. The prime example is a case like:

for (i = 0; i < 1000; i++) {
    for (j = 0; j < 1000; j++) {
        for (k = 0; k < 1000; k++) {
            ...
            if (condition)
                goto break_out;
            ....
        }
    }
}
break_out:

Using a goto to jump out of a deeply-nested loop can often be cleaner than using a condition variable and checking it on every level.

Using goto to implement subroutines is the main way it is abused. This creates so-called "spaghetti code" that is unnecessarily difficult to read and maintain.

bta
  • 43,959
  • 6
  • 69
  • 99
  • 5
    What if there are some automatic objects constructed on the stack, which are local inside the loop? Goto will jump to some other place, jumping over the end of the blocks, where the destructors for these objects are called. Right? In most cases, it won't do anything bad. But there are cases where it WILL do, including losing user's data etc. – SasQ May 12 '12 at 06:21
  • 16
    @SasQ: The compiler is responsible for ensuring that the actual "jmp" instruction generated for the `goto` is preceded by whatever code would be necessary to get rid of inner scope variables. – supercat May 13 '12 at 20:31
  • 3
    It's not true that `goto` can jump between functions. C has `longjmp()` for that, and C++ has exceptions. – celticminstrel Jul 19 '16 at 23:53
  • regarding your claim that "goto can also be used to jump from one function into another without making a function call": [**your claim that you can use `goto` to "jump from one function into another without making a function call" is wrong as explained by here](https://stackoverflow.com/a/17357266/52074) and [here](https://stackoverflow.com/a/17357238/52074) and also see the comment directly above by @celticminstrel. – Trevor Boyd Smith Mar 01 '18 at 18:05
  • @TrevorBoydSmith- You're right, I must have been thinking about `longjmp` (same problematic concept, different interface). Fixed. – bta Mar 01 '18 at 23:18
  • 1
    If you need a `O(N^3)` loop, maybe `goto` is the least of your concerns. – anastaciu Apr 05 '21 at 08:55
  • @anastaciu If you don't ever work with such loops, maybe `goto` is the least of *your* concerns. – Andrew Jun 15 '21 at 07:44
  • @Andrew I try as much as I can, not to, and it's not so hard, I'm very doubtful that any company nowadays accepts a piece of code with over O(N^2), and even O(N^2) is a stretch. – anastaciu Jun 15 '21 at 09:21
  • @anastaciu Plenty of companies would. There is a vast variety of different software out there, and many of them require complicated nesting. – Andrew Jun 16 '21 at 02:00
47

There is nothing wrong with goto in itself. It's a very useful construct in programming and has many valid uses. The best that comes to mind is structured resource freeing in C programs.

Where goto's go wrong is when they are abused. Abuse of gotos can lead to thoroughly unreadable and unmaintainable code.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
33

In 1968, Edsger Dijkstra wrote a famous letter to the editor of Communications of the ACM GOTO is considered harmful in which he laid out the case for structured programming with while loops and if...then...else conditionals. When GOTO is used to substitute for these control structures, the result is very often spaghetti code. Pretty much every programming language in use to day is a structured programming language, and use of GOTOs has been pretty much eliminated. In fact, Java, Scala, Ruby, and Python don't have a goto command at all.

C, C++ and Perl still do have a GOTO command, and there are situations (in C particularly) where a GOTO is useful, for example a break statement that exits multiple loops, or as a way of concentrating cleanup code in a single place in a function even when there are multiple ways to terminate the function (e.g. by returning error codes at multiple points in the progress of a function). But generally its use should be restricted to specific design patterns that call for it in a controlled and recognized way.

(In C++, it's better to use RAII or a ScopeGuard (more) instead of using GOTO for cleanup. But GOTO is a frequently used idiom in the Linux kernel (another source) which is a great example of idiomatic C code.)

The XKCD comic is a joke on the question "Should GOTO always be considered harmful when there are certain specific design patterns that are helped greatly by its use?"

Ken Bloom
  • 57,498
  • 14
  • 111
  • 168
  • 8
    And that GOTO's went out with the (computing) dinosaurs – Gerry Coll Aug 19 '10 at 00:31
  • @Gerry: that's a good one. I hadn't thought of that. – Ken Bloom Aug 19 '10 at 00:38
  • Actually, with the `goto` he used (to `goto` a subroutine of some sort), raptors should attack him. – Ken Bloom Aug 19 '10 at 13:39
  • 1
    I find that the DIjkstra explanation (and its direct consequences) is the true reason not to use goto, and not just the "unstructured code" everybody think it´s all about. There are more implications, and you are right to mention it. – Senua Jan 20 '15 at 13:25
  • Java don't have a `goto` command but a `break` who serve the same purpose – David Doumèche Oct 07 '15 at 07:34
  • You guys should have used C64 Basic V2.0. released more than 10 years after the Dijkstra's paper, this language has neither **else** *nor* the loops, besides a `for` loop that you could misnest by accident. Bill Gates is personally responsible for this abomination, BTW. – Antti Haapala -- Слава Україні Dec 25 '17 at 12:27
  • "Java don't have a goto command but a break who serve the same purpose" No. break is much more limited in scope. Break can only be used to exit the loop prematurely and to exit switch block, which seems to be like a C carryover. – Xwtek Jun 01 '21 at 09:32
10

Did you google the issue?

The founder of the anti-goto movement is Edsger Dijskstra with his legendary "Goto Considered Harmful"

To get you started you can goto (ha ha!) http://en.wikipedia.org/wiki/GOTO

John Smith
  • 12,491
  • 18
  • 65
  • 111
  • 2
    Ironically, he actually tolerated far more GOTO than programmers today. For Djikstra, forward GOTO is okay, backward GOTO and GOTO into the inside of the loop is not. – Xwtek Jun 01 '21 at 09:34
9

It's possible in C++ because it's possible in C. Whether you should or shouldn't use it is long-standing religious war.

It was a design goal of C++ that 99-point-something percent of C programs in the wild should compile and run with the same functionality in C++. Including goto was part of the effort to reach that goal.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171