Search

7.6 — Goto statements

The next kind of control flow statement we’ll cover is the unconditional jump. An unconditional jump causes execution to jump to another spot in the code. The term “unconditional” means the jump always happens (unlike an if statement or switch statement, where the jump only happens conditionally based on the result of an expression).

In C++, unconditional jumps are implemented via a goto statement, and the spot to jump to is identified through use of a statement label. The following is an example of a goto statement and statement label:

In this program, the user is asked to enter a non-negative number. However, if a negative number is entered, the program utilizes a goto statement to jump back to the tryAgain label. The user is then asked again to enter a new number. In this way, we can continually ask the user for input until he or she enters something valid.

Here’s a sample run of this program:

Enter a non-negative number: -4
Enter a non-negative number: 4
The square root of 4 is 2

Statement labels have function scope

In the chapter on object scope (chapter 6), we covered three kinds of scope: local (block) scope, file scope, and global scope. Statement labels utilize a fourth kind of scope: function scope, which means the label is visible throughout the function even before its point of declaration. The goto statement and its corresponding statement label must appear in the same function.

While the above example shows a goto statement that jumps backwards (to a preceding point in the function), goto statements can also jump forward:

This prints:

cats

Beyond the jumping forward, there are a couple of interesting things worth mentioning in the program above.

First, note that statement labels must be associated with a statement (hence their name: they label a statement). Because the end of the function had no statement, we had to use a null statement so we had a statement to label. Second, we were able to jump to the statement labeled by end even though we hadn’t declared end yet due to statement labels having function scope. No forward declaration of statement labels is necessary. Third, it’s worth explicitly mentioning that the above program is poor form -- it would have been better to use an if statement to skip the print statement than a goto statement to jump over it.

There are two primary limitations to jumping: You can only jump forward or backward within a single function (you can’t jump out of one function and into another), and if you jump forwards, you can’t jump forward over the initialization of any variable that is still in scope at the location being jumped to. For example:

Note that you can jump backwards over a variable initialization, and the variable will be re-initialized when the initialization is executed.

Avoid using goto

Use of goto is shunned in C++ (and other modern high level languages as well). Edsger W. Dijkstra, a noted computer scientist, laid out the case for avoiding goto in a famous but difficult to read paper called Go To Statement Considered Harmful. The primary problem with goto is that it allows a programmer to jump around the code arbitrarily. This creates what is not-so-affectionately known as spaghetti code. Spaghetti code is code that has a path of execution that resembles a bowl of spaghetti (all tangled and twisted), making it extremely difficult to follow the logic of such code.

As Dijkstra says somewhat humorously, “the quality of programmers is a decreasing function of the density of go to statements in the programs they produce”.

Almost any code written using a goto statement can be more clearly written using other constructs in C++, such as if statements and loops. One notable exception is when you need to exit a nested loop but not the entire function -- in such a case, a goto to just beyond the loops is probably the cleanest solution.

Best practice

Avoid goto statements (unless the alternatives are significantly worse for code readability).


7.7 -- Intro to loops and while statements
Index
7.5 -- Switch fallthrough and scoping

30 comments to 7.6 — Goto statements

  • Jiri

    Sooo, goto is infact a while loop, the same as for loop is in fact while loop. You only need to play with conditions a bit. It's nice how almost everything can be reduced to if and while :D

  • goto is clear. Thank you sooooo much Alex.

  • Ammm...if  goto moves forward the initialization of x in the above line, doesn't it mean that definition of x was also skipped. And if definition(declaration) is skipped, why compiler doesn't throw any error message (undefined variable x or something like that) and only says invalid forward jump?

    • Alex

      Variable definitions (without initialization) are not actually executed. Storage allocation for variables happens at compile time, not runtime, so the variable will still exist even though C++ jumped over it at runtime.

      It's interesting to note that if this were a class instead of a fundamental data type, the constructor for the class wouldn't not get executed if the variable's definition was jumped over, even though memory for the class would be allocated!

  • Label is a mark used to tell the machine that it should restart execution from this point, if a goto statement occurs. Am I right?

    It's still unclear to me why this doesn't compile. The above code compiles fine if  x is left uninitialized. Will you please elaborate what's happening here?
    Thanks...:)

    • Alex

      You can't use a goto to move forward past a variable initialization. If you jump over the initialization of x = 5, then what would you expect x += 3 to do?

  • Todd

    Your link to "Go To Statement Considered Harmful" seems to be outdated/inaccessible. I could find the paper only through the search bar in the link you provided)

  • Rancho

    Woow, this is good. please i need an example of replace(),erase() and find() funtion. thanks

  • ProgrammerJupiter

    I was just curious if it was possible to call the goto a place mentioned after goto. I know this rly is illogical but i want to bypass certain if statements, if possible

  • Hi,
    Ya this is good example for understanding GOTO Statement...but i have another example it's so easy to understand how goto work and we can see result easily ok....thanks a lot for giving us a most useful information about c++...

    #include <iostream.h>
    #include <conio.h>
    
    void main()
    {
       
        int n,x,sum=0,ch;
    tryAgain: // this is a statement label
        cout<<"n Enter any number";
        cin>>n;
    sum=sum+n;
    cout << " Press 1 for Add new Number Or Press any number for exit ";
    cin>>ch;
       if (ch==1)
       goto tryAgain; // this is the goto statement
       cout << "n Sum of all Given Number" << sum;
    getch();
    }
    
    • Alex

      It's clearer without the goto:

  • Karl

    It would have been nice to just make the compiler a little more intelligent so that it would check for accesses to a variable whose initialization was skipped by a goto.

    When dealing with C interfaces, goto helps make the code MUCH easier to read and follow when used as a short-circuit to cleanup code after an error condition is encountered, especially when you have a long chain of code that is dependent on a successful return value of the previous function call, which is itself dependent on an earlier call, and so on (as tends to happen when dealing with system-supplied opaque data types). The alternative is a big mess of nested, error prone if-then-else statements to handle cleanup and error logging, or throwing an artificial exception to be caught within the same method (essentially a glorified goto).

    Indeed, even Dijkstra concedes the use of goto in abort clauses:

    "One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs, but whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way."

    • Alex

      C programmers often use goto in places where cleanup is needed after an error condition.

      In C++, this is not recommended, as better and more robust mechanisms exist, such as exception handling and destructors.

  • Canute
     Hello Alex, first off I would just like to thank you so much for taking the time to write this tutorial, it is the best online one I have seen yet. My question is what is a good example of code where you NEED a goto statement? Like Kaonashi said I'm pretty new to programming and I used to use GOTO for everything. It got extremely tedious debugging the code or even adding something else. Thanks in advance -Canute
    

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">