Saturday, July 5, 2025

GOTO explained

 There is a keyword in Java that can’t be used, and hasn’t been used in modern programming languages for decades, but it’s worth discussing because it brings up a point about how to write good, clean code (hint: by not ever using this keyword anywhere). This is, of course, the goto (or go-to, or GOTO, depending on the language; in Java, the reserved word is “goto” all lowercase, no hyphen) statement condemned by none other than Edgar Dijkstra himself, long before Java was invented.

GOTO was initially devised as a part of a branching or looping instruction (as in: “if this is true, GOTO this line and do xyz, else GOTO this other line and do abc” or “while this is true, do this, then GOTO this place to check the loop condition”).  But, very quickly, problems came about with GOTO as an introducer of spaghetti code.

People used to number the lines of their code, and feed those line numbers into GOTO to tell it where to jump to. Most of the time, people would write successive lines of code separated by 10; the first line was line 10, then 20, then 30, and so on. These gaps  were put in place so that, if there was ever a bug, there would be numeric space in between to, later in the file, insert a fix at an available line number, even out of counting order, and then use go-to to come in or out of the fix as needed.

But, of course, as programs get longer and more complex, mistakes become simultaneously more common and more difficult to fix, so the need for these kinds of goto statements jumping around the code increases rather rapidly, much faster than the length of the code. That is, a piece of code that has twice as many lines, probably has more than twice as many bugs (and therefore needs more than twice as many of these goto statements).


This example is in C, not in Java, but it illustrates the messiness just as well:

#include <stdio.h>

 

int main() {

    int value = 42;

 

    printf("Start of program\n");

 

    // Suppose this block is buggy

    goto skip_buggy_code;

    printf("This buggy code would crash!\n");

    value = value / 0; // Division by zero bug

 

skip_buggy_code:

    printf("Buggy code skipped. Value is %d\n", value);

 

    // Another bug

    if (value == 42) goto avoid_null_pointer;

    int *ptr = NULL;

    printf("Dereferencing null pointer: %d\n", *ptr); // Would crash

 

avoid_null_pointer:

    printf("Null pointer dereference avoided.\n");

 

    printf("End of program\n");

    return 0;

}

Using goto with line numbers (or in this C example—linguistically developed enough to have labels already) creates incredibly messy code that is hard to follow. Imagine trying to read an essay written by a student who writes clearly, versus reading an essay by a student who constantly circles things, crosses them out, indicates that a paragraph is in the wrong place, and so on. The first student’s work would be easier to understand than the second, even if, presentation aside, the second student did bring up some good points in the essay.

This messiness—or, rather, avoiding it—is why Java does not support GOTO behavior, and, further, prevents any use of anything even remotely similar by taking that word out of the list of possibly allowed user-defined symbols. You therefore cannot implement a method with that name, nor give the name to a variable or a class. 

No comments:

Post a Comment

Switch

 Other than if/if-else/if-else if-else and the ternary operator, there is yet another common and important conditional expression in Java th...