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_begin
is the same as thecontinue
statementgoto loop_end
is the same as thebreak
statement
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.