Is goto evil?

What is goto?

A goto statement typically performs an unstructured jump within a program, and may be a legacy of the jump instructions found in assembler code. Its use was popular in the early years of programming, before the advent of structured programming in the 1960s and 1970s. Its first use was likely Fortran, and subsequently Cobol. Fortran eventually incorporated structured programming in the 1970s, and the dependence on goto declined. It was still incorporated into languages that followed such as C and Ada, but is missing from Java and Python. Many controls structures had their origins in the goto statement. The conditional goto used in Fortran to jumping over code evolved into the if statement with a compound body. The conditional goto for repetition turned into the structured repetitive loops: for, while, do-while, repeat-until etc. The conditional goto for jumping out a loop evolved into the break statement.

Is goto still considered harmful?

In 1968 Edsger Dijkstra wrote an article published in Communications of the ACM titled “Go-to statement considered harmful”. The paper was frequently referenced in the ensuing years, and may have laid the groundwork for the demise of unstructured programming. Ironically, Dijkstra acknowledges in “What led to ‘Notes on Structured Programming’” that the original paper was titled ‘A case against the goto statement’, and was changed by the editor, Niklaus Wirth.

A program composed entirely of assignment statements is easy to trace, because its flow is sequential, there are no unstructured branches. The addition of conditional statements doesn’t change things that much, the process still remains linearly sequential, although different paths through the code can be taken. Adding repetition statements makes the code more complex, but does not make it unstructured – it is always possible to easily trace through the code. The addition of unstructured jumps makes it much more challenging to trace through a program. In Dijkstra’s words, the goto statement is “just too primitive”, a structure which makes proving program correctness much more challenging.

So why is goto considered harmful? The #1 reason may be that it is possible to use goto in such a manner that it obscures the structure of a program to the point where it becomes impossible to decipher.  William Wulf in his paper “A Case Against the GOTO” puts it another way: it is possible to use the goto to fabricate a “rat’s nest” of control flow. Let’s not forget that early languages had little in the way of structure – nearly everything was achieved using goto statements. In early Fortran, if statements were limited to a single statement, compound statements required the use of a goto statement. To perform a block of code if the value of a variable X is less than 100 required writing a statement of the form:

    IF (X .GE. 100) GO TO 50
    ...code executed if X<100
50

There was also no else statement, so a corresponding statement can be similarly fashioned:

    IF (X .GE. 100) GO TO 50
    ...code executed if X<100
    GO TO 100
50
    ...code executed if X>=100
100

Loops were created in the following manner:

   I = 0
10 I = I + 1
    ...do something in the loop
   IF (I .NE. N) GO TO 10

This may have precipitated the move to structured programming. 

One can take the adage that “goto doesn’t create bad code, bad programmers do”, but essentially before structured programming there was goto, often producing a spaghetti like code. One doesn’t really appreciate the context of this until having translated a program from a “legacy” language such as Cobol or Fortran – one that contained a myriad of goto statements disguised in various forms. For example, in Fortran, there was:

the computed GO TO:

GO TO (210,220,230,240,250), i

the unconditional branch

GO TO 400

the assigned goto

GO TO N, (10,20,30,40)

and the arithmetic if (performs the same sort of unstructured branching)

IF (N) 10,20,30

Consider the following Fortran code containing a series of arithmetic if statements, and two go to statements which mimic the effect of loops:

primenumberJumps

One or two goto’s in a small program may not seem like a travesty, when they start to comprise one of the core structures in a program, the program becomes too unstructured to analyze properly. The sample Fortran program shown above is 22 lines long, and contains six unstructured jumps. Imagine what longer programs would look like?

Code containing gotos is also harder to format, and reduces the efficiency of compiler optimizations. Source code optimizations differ from the efficiencies obtained at compiler time. The use of the goto also violates the principles of structured programming. In languages such as Fortran, especially earlier dialects, loops often existed in the form of free loops, hand built structures that were dependent on the proper branching logic. For example consider the following code shown in both Fortran and C:

loopingGoto

The problem here is that the program iterates infinitely, a legacy of the minus sign in I=I-1, which should be a + sign. I becomes negative, and the if statement never fails. Using a for loop in the case of the C program would not allow this to happen.

Modern dialects of Fortran have all but made obsolete several of these Fortran goto’s including computed go to and assigned go to.

When to jump around?

Sparse use of goto statements can be okay, for experienced programmers in specific circumstances. For example, using a single goto and single label to exit several levels of scope, or using a goto in the middle of complex construction to short cut to the top of a loop. It may also be used in error handling where there in the absence of exceptions. 

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.