Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site rtp47.UUCP Path: utzoo!watmath!clyde!bonnie!akgua!mcnc!rti-sel!rtp47!throopw From: throopw@rtp47.UUCP (Wayne Throop) Newsgroups: net.lang.c Subject: C Style (goto or not goto, that is the question) Message-ID: <190@rtp47.UUCP> Date: Sun, 15-Sep-85 15:06:18 EDT Article-I.D.: rtp47.190 Posted: Sun Sep 15 15:06:18 1985 Date-Received: Tue, 17-Sep-85 04:51:55 EDT References: <180@chinet.UUCP> Organization: Data General, RTP, NC Lines: 98 > 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!mcnc!rti-sel!rtp47!throopw