C Style (goto or not goto, that is the question)

Wayne Throop throopw at rtp47.UUCP
Mon Sep 16 05:06:18 AEST 1985


> The question:
>         Which of the following code segments is more understandable,
>         (readable, structured, etc) given the current attitudes
>         about the presence of goto's in programming?
>                       ...
>         If you had to modify this program, written by someone else who
>         commented it sparsely, which style would you prefer to work on?

I've left the (more or less) original two versions to the end of this
article.  I note that they don't do the same thing, and thus are not
valid comparisons.  I also note that a "for" is used where a "while"
should be used, causing the "non goto version" to be less comprehensible
than it should be.  My conclusion: I wouldn't want to have to modify
either of the original code segements.

In any event, here is a similar example pair:

    ...
    init_screen();
    for( read_command(); invalid_command(); read_command() )
        display_error();
    execute_command();
    ...

vs
    ...
    init_screen();
  retry:
    read_command();
    if( invalid_command() ){
        display_error();
        goto retry;
    }
    execute_command();
    ...

I prefer the first.  I am guaranteed that there is only one way to enter
this code fragment, and only one way to leave it (barring longjmp).  The
second fragment has no such assurance... it can be entered in the middle
from anywhere in the containing function.  Thus, the entire function
must be searched for references to the label just to be sure that the
conditions that must be met for the code that follows the label are met
everywhere there is a goto that label.

I tend to agree with the usual wisdom that setjmp, longjmp, goto, and
other labeled transfers of control are useful in error or exception
processing, and are pure obfuscation in almost every other case.  The
example was a sort of error recovery, but not one where the obfuscation
of a goto was waranted to bail out of the situation.


Note that the problem with gotos isn't the goto... it's the come-from.
That is, the code around the goto isn't unclear.  The code around the
*label* is unclear.  Thus, the C goto could be tamed somewhat if only
one could scope label reference appropriately.  For example, a lint-like
tool could allow only one label to appear in any compound statement, and
could allow gotos to that label only from within that compound statement
(and only from *before* the label).  This would assure that

    {   ...
             goto bailout;
        ...
    bailout:
        ...
    }

would be a one-entry one-exit structure, and go a long way to "taming"
the goto.  There are still many (potential) ways for control to reach
the "bailout" label, but it is clearer where to look for them.

Comments?


[Examples from original posting for reference.]
> GOTO VERSION:
>         . . .
>         noecho();
> retry:
>         move(4,10);
>         refresh();
>         ch = getch();
>         if ((ch < '1' || ch > '5') && ch != 'E')
>         {
>                 putchar(BELL);
>                 goto retry;
>         }
>         addch(ch);
>         refresh();
>         . . .
>
> versus NO GOTO VERSION
>
>         for ( ; (((ch=getch()) < '1' || ch > '5') && ch != 'E') ; )
>                 putchar(BELL);
>         addch(ch);
>         refresh();
-- 
Wayne Throop at Data General, RTP, NC
<the-known-world>!mcnc!rti-sel!rtp47!throopw



More information about the Comp.lang.c mailing list