cstatecontrol-flowprocedural-programming

GOTO, CONTINUE, BREAK in procedural programming, how do they effect state?


In my attempt to gain a better knowledge of procedural programing, both for practical and academic use I am trying to clarify the effect CONTINUE and BREAK statements have on state.

I have come to understand that GOTO is essentially forbidden as I go with the if you're a good programmer you can find a better way approach. However I also understand at a deeper level that it is to be avoided in procedural programming because it lacks the ability to change state.

This is were I get confused, how is it that CONTINUE, and BREAK can change state?

My initial thought was that because a GOTO is as such:

GOTO A;
LBL A;

No expressions are evaluated and no state is changed. And combined with the form of a CONTINUE:

while (evalFunction(*value) == 1) {
  ..
  if ( bail == 1 ) continue;
  ..
}

Has the ability to change state in the while condition.

However this does not account for BREAK.

Can someone provide some more detail regarding the specifics in procedural programming?


Solution

  • I don't know where this "ability to change state" thing comes from.

    The highest virtue of code is readability. GOTO is to be avoided because it often makes the code hard to read, and for no other reason. There are in fact cases where code that uses GOTO is easier to read than it would be if GOTO were avoided, and in those cases, GOTO should be used. A good example is the C nested cleanup idiom:

    int do_something()
    {
       int rv = -1; /* failure */
       Foo *foo = get_a_foo();
       if (!foo) goto out;
       Bar *bar = get_a_bar();
       if (!bar) goto out_foo;
    
       rv = do_something_with_foo_and_bar(foo, bar);
    
       release_bar(bar);
    out_foo:
       release_foo(foo);
    out:
       return rv;
    }
    

    This is easier to read than the alternative with nested if statements, because normal control flow is emphasized. (In C++ you would use RAII instead, of course, for even less clutter.)

    Similarly, BREAK and CONTINUE can make the code harder to read, and should be avoided when they do; however, they are in nearly every modern language because they often make code easier to read. So they are preferred to complicated if-else constructs inside loops and/or contorting the logic so that the loop exit condition can be tested at the top of the loop.