Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!ames!oliveb!pyramid!voder!kontron!optilink!cramer From: cramer@optilink.UUCP (Clayton Cramer) Newsgroups: comp.lang.c Subject: Re: Put your code... (was Re: gotos Message-ID: <2030@optilink.UUCP> Date: 27 Apr 88 19:00:54 GMT References: <2597@ttrdc.UUCP> <165600044@uiucdcsb> Organization: Optilink Corporation, Petaluma, CA Lines: 76 > > [Part 6. Panic exits] > > The notion of using a _goto_ for a panic exit condition is touched on > by Knuth only in passing. > > There are many cases, generally ignored in the academic training that > computer scientists receive, where a complicated operation can be > interrupted by the occurrence of an unexpected condition. Generally, > the result of such an interruption, in classroom exercises, is to > terminate the program. Simply aborting is, however, unacceptable in > the real world; for instance, a text editor that aborts (and quite > possibly destroys the user's file) when the user makes an error (or > the system detects one) is nearly unusable. > > Unquestionably, a program that can encounter an unexpected condition > in an inner structure can recover by testing for that condition in all > the containing structures. Such tests, usually written as statements > like > > if (error_detected) break; > > while (... && !(error_detected)) .... > > error_detected != do_function (....) > > both clutter the code and are a decided performance expense at run > time, as they repeat the tests for errors in all the loops of the > program. > > In many of these cases, it is advisable to, instead of repeating > tests, simply insert code of the form > > if (failure) goto error_handler; > > at the point where the failure can occur. Since the objective is do some cleanup (close the editor's files, spray error messages on the user's screen, post an article about the failure on USENET, etc.) before giving up, the correct solution is; if (failure) ErrorHandler(__FILE__, __LINE__); ErrorHandler (FileName, LineNbr) char *FileName; int LineNbr; { /* Clean up everything. */ . . . /* Print out complaints. */ fprintf (stderr, "This software self-destructed at %d in %s\n", LineNbr, FileName); exit (9000); } Note that this gives the catastrophic failure cleanup the poster was saying was needed before killing the process, without the evil goto. Note also that calling a function, rather than using a goto makes it possible to pass information about the failure (in this case, what line and filename was where the error occurred), where the goto approach requires the use of global variables. > Moral: Using _goto_ may be acceptable to break a deep nest of control > structures in the event of an unusual occurrence. This usage is quite > possibly the only acceptable context for _goto_. > > [End of part 6.] Very true. But for the case described, calling a function that does an exit is STILL preferable to a goto. Clayton E. Cramer