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"