GOTO is Not Pure Evil
From garbage collection, hard to debug code, infinite loops, and other notorious bugs, there is quite a list of issues in using the GOTO statement. Due to GOTO's bad reputation, it's hardly being used and most programmers do not even know that such a control statement exists.
Let's take a look at the most common issues of GOTO statements and see if these assumptions are true. Otherwise, your idea that "GOTO is BAD" is just indoctrination!
- Garbage Collection
Jumping out a routine without deallocating objects could cause memory leaks. But the same could be said for any kind of loop that breaks or returns without proper garbage collection. Although releasing of objects upon exit of a function scope, destruction, or main program exit, is done automatically by most programming languages, some allow you to have total control of the program flow, which causes memory leaks if your program is poorly coded.
Two program snippets below show how GOTO and BREAK statements are used in a similar manner.
// Using goto // Using Break
Node *n; Node *n;
while (1) while (1)
{ {
n = new Node; n = new Node;
... ...
goto quit; break;
... ...
delete n; delete n;
... ...
} }
quit:
return 0; return 0;Is GOTO really to blame or the bad programmer in this case? As you can clearly see, the garbage collection problem due to GOTO is just a myth.
- GOTO Loops are Hard to Read and Debug
Is the claim "GOTO Loops are confusing" true or not?
start1:
...
start2:
...
start3:
...
if (exitCondition3) goto start2;
goto start3;
if (exitCondition2) goto start1;
goto start2;
if (exitCondition1) goto exit;
goto start1;exit:
return 0;The code above can be exactly written in the following DO-WHILE Loop:
do
{
...
do
{
...
do
{
...
} while (exitCondition3);
} while (exitCondition2);
} while (exitCondition1); return 0;GOTO Loop Structures that resemble DO-WHILE or FOR loops are not hard to read. But what makes it confusing is the introduction of the so-called "Spaghetti Loops" especially in deep iterations.
start1:
...
specialCaseStart:
...
goto gobackwherecalled;
...
start2:
...
start3:
...
if (specialCase) goto specialCaseStart;
gobackwherecalled:
...
if (exitCondition3) goto start2;
goto start3;
if (exitCondition2) goto start1;
goto start2;
if (exitCondition1) goto exit;
goto start1;exit:
return 0;Spaghetti Loops are irrefutably messy, but why even structure your code this way? If there will be repeated calls to specialCase Label, consider making it a function. The trick below shows how this is done.
start1:
...
specialCaseFunction();
...
start2:
...
start3:
...
if (specialCase) specialCaseFunction();
...
if (exitCondition3) goto start2;
goto start3;
if (exitCondition2) goto start1;
goto start2;
if (exitCondition1) goto exit;
goto start1;exit:
return 0;Spaghetti Loop is a bad choice, just like choosing using WHILE to replace a simple IF statement.
// Simple IF // Complicating the structure
// Using While
if (a > max) while (a > max)
max = a; {
max = a;
break;
}
Spaghetti Loops are hard to debug as the programmer could lose sight of breakpoints resulting in infinite loops, memory leaks, and other unexpected bugs. As a rule of thumb, don't use GOTO statements to write Spaghetti Loops. Using GOTO that resembles a DO-WHILE or FOR is just fine.
Now, let's discuss some practical usage of GOTO.
- GOTO statement is convenient for exiting deep iterations. You don't have to use additional variables to flag an exit. The code below demonstrates this convenience.
// Using GOTO // Using Flag Variables
bool needExit = false;
for (i = 0; i < I; i++) for (i = 0; i < I; i++)
{ {
for (j = 0; j < J; j++) for (j = 0; j < J; j++)
{ {
for (j = 0; j < J; j++) for (j = 0; j < J; j++)
{ {
if (some condition) if (some condition) {
goto exit; needExit = true;
break; }
... ...
} }
if (needExit) break;
... ...
} }
if (needExit) break;
... ...
} }exit:
... Some clean-ups here
- GOTO statements can be used as transient loops for converting recursions to iterated stacks due to its simplicity. Once all the transient loops have been identified, conversion to regular DO-WHILE or FOR Loops follow. The program below is a half converted recursive Fibonacci Function where the last end recursion is replaced by a GOTO statement.
int fibo(int N)
{
int t = 0;
start:
if (N <= 1)
{
t += 1;
goto last;
}
t += fibo(N - 1);
N = N - 2;
goto start;
last:
return t;
}An article discussing the Removal of Recursion can be found by following the link here.
- GOTO statement is a fancy alternative to DO-WHILE, or FOR Loops. Show off your programming skills to newbies by using the forbidden control statement. It's also a fancy way to experience low-level programming, as its behavior is similar to Assembly Language's JMP instruction.
- GOTO is more intuitive than the DO-WHILE and FOR Loops, and can be used to teach programming to kids thru a flowchart. In fact, an old book called "COMPUTERS by Neil Ardley" below demonstrates converting a flowchart to GWBASIC.
To be clear, I'm not a fan of GOTO - the Spaghetti Loop is a strong case against it (an attribute that cannot be avoided). But other than that, GOTO Statements are only as bad as your programming skills.