C89-Goto: Loops
In my previous article I explained the history behind the keyword briefly and shared my opinion on the goto statement. Today I'll quickly demonstrate how goto can be used to emulate loop control structures. It is shown here for educational purpose only, I doubt anyone is waiting to see this in their production code unless the language only has support for if-else and goto.
A while loop looks like this in C89:
/* while: statement */
int i = 0;
int s = 10;
while (i < s)
{
printf("%d", i);
++i;
}
printf("done!");
What it does step-by-step is this:
- check if condition is met
- yes: terminate loop
- no: run loop:
- print the value of the iterator (
i) - increment our iterator (
i) - iterate to the next cycle
- print the value of the iterator (
It would look like this in goto:
/* while: goto-begin_label */
int i = 0;
int s = 10;
loop_begin:
if (i < s)
{
printf("%d", i);
++i;
goto loop_begin;
}
printf("done!");
- check if condition is met
- yes: don't run scoped code
- no: run scoped code:
- print the value of the iterator (
i) - increment our iterator (
i) - jump back to restart (
goto loop_begin;)
- print the value of the iterator (
To explain how break and continue work, I'll use a slightly more goto-intensive solution:
/* while: goto-all_labels */
int i = 0;
int s = 10;
loop_begin:
if (i >= s) goto loop_end;
printf("%d", i);
++i;
goto loop_begin;
loop_end:
printf("done!");
You probably notice that the while: goto-all_labels example is very flat in structure, and that it reads much more like assembly than a conventional programming language. This is indeed true, because the code above is more or less what a compiler would translate our loop to in readable form.
What essentially happens in the example:
- check if condition is met
- yes: terminate loop (
goto loop_end;) - no: continue executing
- yes: terminate loop (
- print the value of the iterator (
i) - increment our iterator (
i) - jump back to restart (
goto loop_begin;)
For those paying attention, you can observe that:
goto loop_beginis the same as thecontinuestatementgoto loop_endis the same as thebreakstatement
This holds true for labled breaks as well. break, continue and variations thereof, as well as for, foreach and switch-case are all just goto in sheeps clothing.
A do-while loop would look like this:
/* do-while: goto */
int i = 0;
int s = 10;
loop_begin:
printf("%d", i);
++i;
if (i >= s) goto loop_end;
goto loop_begin;
loop_end:
printf("done!");
All we really have to do if move the goto loop_end; just above the goto_begin to ensure everything is at least executed once.
Conclusion
Hopefully you now understand how while. do-while, break and continue can be emulated using the goto statement. In the next article I'll explain how goto can be used to emulate the switch-case control structure.