GOTO has one (and only one) use (IMHO - supported, naturally :-), by some great computer scientists...). That is to effect abnormal termination of a program.

continue and break in C are both implicit GOTOs. Other languages have similar constructs, designed (it seems) to provide a word other than "goto" for, essentially, the same function.

Another C example is the use of return at multiple points in a function. Many purists consider this as "harmful" as excessive use of GOTO.

Compared to COBOL's ALTER statement, GOTO is positively structured!

Among programmers, using the goto statement is generally considered evil (see: spaghetti code). 
In fact, Java doesn't even have this statement since it is so wrong. 

Instead, one can use the continue and break statements to structure a complicated control flow, which is as close to goto as you will get with Java.  Optionally, one can use label statements in conjuction, as illustrated in the Java code below which prints out a few positive even integers:

    searching: for (int i = 0; i <= 10; i++) {
        even: {
            if (i % 2 == 1) {
                break even;
            }
            if (i == 0) {
                continue searching;
            }
            System.out.println("Even positive number: "+i);
        }
    }
The output of this code is:
Even positive number: 2
Even positive number: 4
Even positive number: 6
Even positive number: 8
Even positive number: 10

GoTo (http://www.GoTo.com) is a search engine that allows advertisers to "bid" on search results. Each Web site that wants to be displayed higher in the search results for a particular keyword bids a certain amount of money per clickthrough. The highest bids are displayed first on the page, followed by lower bids, followed by non-bidding matches. Every time a user clicks on a link, GoTo charges the advertiser the amount of their bid.

The end result is a search engine that works more like the Yellow Pages, displaying matches to high-bidding commercial sites before any matches by content. A sample search for "linux" turned up hits for Linux servers, Linux training, Linux toolkits... and finally, on the second page starting with match #72, links to Linux news, documentation, and distributions. In contrast, Google counts the number of links to a Web page to determine how high to display a match, resulting in a list sorted by how many other Web users consider a site useful. They're not at all sneaky about this model; in fact, they promote it right on their front page and list the amount each advertiser has bid right on the search results page.

Despite their cynical techniques, GoTo is a success in the business sense. Google is the number one search engine because it's so good (and is fully integrated with Yahoo!), but GoTo is number two because they've partnered so widely, have a paid affiliate program, and are actually profitable.

In languages like C, goto is particularly useful when you're cycle-shaving and don't trust the compiler's optimizer to do the right thing. This is seen regularly in the Linux kernel source.

Consider the following snippet:

  x = (*ptr);
  if (x==0) {
    *ptr = -1;
    failures++;
    return;
  }
  *ptr2 = x;
  ...
  return;

Now assume that (x==0) is the exception and not the common case. When this is boiled down to machine instructions, without any code reorganization or reordering, it would look something like this on a RISC-ish machine:

   ld R1, (R2);
   bnz R1, a;
   sub R1, R0, 1;
   st (R2), R1;
   add R3, R3, 1;
   RETURN;  # macro handling the stack frame etc...
a:  
   st (R4), R1;
   ...
   RETURN;

See the problem? That bnz instruction will usually be taken; if the processor has a simple pipeline, then the sub inside the "exception" code block will already have been fetched and will have to be invalidated while the target instruction is fetched. (Granted, some more involved branch prediction techniques can reduce this effect, but even then they usullay rely upon a warm cache to make the right choice.)

What would really be great is if the machine code looked like this:

    ld R1, (R2);
    bez R1, b;
    st (R4), R1;
    ....
    RETURN;
b:
    sub R1, R0, 1;
    st (R2), R1;
    add R3, R3, 1;
    RETURN;

See what we've done? The branch is now not taken in the common case, thus the instruction pre-fetch of the store is allowed to proceed and execute without a stall. Even better.

But what if we don't trust our compiler to do this little trick for us? Well, we can write our code in a way that maps to this construct directly. We have two options.

The first would look something like this:

  x = (*ptr);
  if (x!=0) {
    *ptr2 = x;
    ...
    return;
  } else {
    *ptr = -1;
    failures++;
    return;
  }

This is good form if we have only one or maybe two such predicates in a code block. However, if there is a series of five of them, then the nesting quickly obfuscates the intent of your code.

The other alternative looks something like this:

  x = (*ptr);
  if (x==0) 
    goto problem;
  *ptr2 = x;
  ...
  return;

problem:
  *ptr = -1;
  failures++;
  return;

Ah, a hacker's view of paradise. The meaning is clear - code is speech. The optimal strategy for the compiler is trivial. And we have prided ourselves on showing our middle school computer class teacher that the mighty and venerable goto does indeed have its place in the toolkit of the modern code jockey.

Use knowledgably, sparingly, and tastefully.

One use of the goto that is commonly overlooked is it's use in writing code based on a state machine (such an Finite State Automaton for those of you following in your CS texts) where a state transition can't be smoothly done in the regular program flow.

Granted, a table could be constructed to represent your states and the transitions, and you could jump arround inside the table, however this would result in the program logic (the state transition table) being represented as program data and not executable code.

Since many modern processors have separate data and instruction caches, this could result in a significant decrease in performance when working on large amounts of data that would be difficult for the compiler to optimize out.

Using gotos in this way is fundamentally different than using them to fiddle with a for loop like zbuffer mentions above. While the example from the kernel is used as a work around for the compiler not creating optimal assembly code, using gotos in your state machine rather than using a table results in the machine actually being compiled to assembly.


With my defense of the goto out of the way, I have two warnings. First, if you don't understand what a state machine is, you probably shouldn't use one. Secondly, if you don't need brutal optimizations, a simple loop to dance around a staticly defined state table will be simpler to read & modify and less prone to errors.

Log in or registerto write something here or to contact authors.