[comp.lang.c] Is it ok to use a goto in given example not trivial, not wizard level

ari@eleazar.dartmouth.edu (Ari Halberstadt) (09/17/89)

Yes, I know that the subject of goto's has been hashed over repeatedly,
but I'd really like the nets opinions on the following use of gotos.
Replies may be emailed to me, and I will summarize [to cut down
on our overloaded group -- more about that another time].

The following code is from a program written for the Macintosh. It's
an initialization function, modeled after the idea of NewWindow(), for
those Mac programmers out there. Exactly what the function does
is unimportant, so I've deleted some chunks of code.

The function must build a structure containing information about a window.
Much of this information involves storage allocation, and since it
is not possible to guarentee the availability of the memory, I had
to figure out some way to allocate the memory and, in the event
of a failure, deallocate as much as was allocated. It wasn't practical
to do something of the sort:
	if (this call fails) {
		clean up everything done up to this point
		return
	}
since this approach introduced the problem of having several places in
the code know exactly what preceded them, and also having the same code
repeated. Having many nested if's was also not a good alternative,
since it meant embedding lots of code deep within the nested if's,
and having it all run off the screen at that! Basically, I think
I've made a crude exception handling facility; a much nicer one
would be in the style of OOP [as implemented in Eifel].

So, after much intro, here's the code:

SWHandle
SWNew(theWindow, viewRect, flags) /* create a scrollable window */
WindowPtr	theWindow;	/* the window to place stuff in */
Rect		*viewRect;	/* rectangle enclosing text and scroll bar */
SWFlags		flags;		/* various flags for the scroll window */
{
/* note: a handle is a pointer to a pointer; it's that weird mac stuff */
	SWHandle	theScrl;
	TEHandle	TEH;
	ControlHandle	vScrl;
	GrafPtr		savePort; /* this thing's a pointer */
	
	GetPort(&savePort);
	SetPort(theWindow);
	theScrl = NULL; TEH = NULL; vScrl = NULL; ScrollAdded = FALSE;
	
	/* create scroll window */
	theScrl = (SWHandle) NewHandle((long) sizeof(SWRec));
	if (! theScrl)
		goto memerr;
	
	/* create the vertical scroll bar */
	/* stuff deleted */
	vScrl = NewControl();
	if (! vScrl)
		goto memerr;
	
	/* create the text edit record */
	/* stuff [and variables] deleted */
	TEH = TEStylNew(&TEViewRect, &TEViewRect);
	if (! TEH)
		goto memerr;

	/* put together the parts of the scroll window */
	(**theScrl).vScrl = vScrl;
	(**theScrl).TEH = TEH;
	
	/* add the scroll window to the scroll list */
	if (! (ScrollAdded = AddScrl(theScrl)))		
		goto memerr;

	SetPort(savePort);
	return(theScrl);
	
memerr:
	if (ScrollAdded && theScrl)	RemoveScrl(theScrl);
	if (theScrl)	DisposHandle((Handle) theScrl);
	if (vScrl)	DisposeControl(vScrl);
	if (TEH)	TEDispose(TEH);
	SetPort(savePort);
	return(NULL);
}

--

-- Ari Halberstadt '91, "Long live succinct signatures"
E-mail: ari@eleazar.dartmouth.edu	Tel: (603) 640-5687
Disclaimer: "Live Free or Die"