Put your code... (was Re: gotos

Clayton Cramer cramer at optilink.UUCP
Thu Apr 28 05:00:54 AEST 1988


> 
> [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



More information about the Comp.lang.c mailing list