lp0 on fire

My personal blog

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:

  1. check if condition is met
    • yes: terminate loop
    • no: run loop:
      1. print the value of the iterator (i)
      2. increment our iterator (i)
      3. iterate to the next cycle

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!");
  1. check if condition is met
    • yes: don't run scoped code
    • no: run scoped code:
      1. print the value of the iterator (i)
      2. increment our iterator (i)
      3. jump back to restart (goto loop_begin;)

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:

  1. check if condition is met
    • yes: terminate loop (goto loop_end;)
    • no: continue executing
  2. print the value of the iterator (i)
  3. increment our iterator (i)
  4. jump back to restart (goto loop_begin;)

For those paying attention, you can observe that:

  • goto loop_begin is the same as the continue statement
  • goto loop_end is the same as the break 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.