Xref: utzoo misc.misc:5961 comp.misc:5962 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ncar!tank!uwvax!uwslh!lishka From: lishka@uwslh.UUCP (a.k.a. Fish-Guts) Newsgroups: misc.misc,comp.misc Subject: Re: The "evil" GOTO (Was: 25 Years of BASIC) Message-ID: <424@uwslh.UUCP> Date: 5 May 89 14:31:54 GMT References: <1791@ubu.warwick.UUCP> <1436@onion.reading.ac.uk> <1814@ubu.warwick.UUCP> <24044@agate.BERKELEY.EDU> Reply-To: lishka@uwslh.UUCP (a.k.a. Fish-Guts) Organization: U of Wisconsin-Madison, State Hygiene Lab Lines: 99 In article <24044@agate.BERKELEY.EDU> ked@garnet.berkeley.edu (Earl H. Kinmonth) writes: > >Since 1979 I have been programming in C. I have written C code into the >high six-figures (lines of code). There has not been one case where a >goto seemed appropriate. When I was tempted, reflection and analysis >convinced me that a goto solution was inappropriate. You may not have been writing code where "goto"'s can be a life saver. Here are two quotes from the writers of C and C++ on where goto's are actually useful: From _The_C_Programming_Language_ by B. Kernighan & D. Ritchie: C provides the infinitely-abusable _goto_ statement, and labels to branch to. Formally, the _goto_ is never necessary, and in practice it is almost always easy to write code without it. We have not used _goto_ in this book. Nonetheless, we will suggest a few situations where _goto_'s may find a place. The most common use is to abandon processing in some deeply nested structure, such as breaking out of two loops at once. The _break_ statement cannot be used directly since it leaves only the innermost loop [...]. This organization is handy if the error-handling code is non-trivial, and if errors can occur in several places. [...] Code involving a _goto_ can always be written without one, though perhaps at the price of some repeated tests an extra variable. [...] Although we are not dogmatic about the matter, it does seem that _goto_ statements should be used sparingly, if at all. From _The_C++_Programming_Language_ by B. Stroustrup: C++ possesses the infamous _goto_. [...] It has few uses in general high-level programming, but it can be very useful when a C++ program is generated by a program rather than written directly by a person [...]. The _goto_ can also be important in the rare cases when optimal efficiency is essential [..]. One of the few sensible uses of the _goto_ is to break out from a nested loop or switch [...]. So there are the comments, "straight from the horses' mouthes!" There are times (especially when writing recursive-descent compilers) when the use of one _goto_ or longjmp() can save many, many additional tests. Note that the setjmp()/longjmp() functions are just a _goto_/label equivalent that can jump across functions (by unwinding the stack). _Goto_ does have its place! >Some months ago, I rewrote GNUtar (an early version) to run under >MSDOS. The original author, in the name of "efficiency" had used a >large number of goto(s). As is common with such programming, he had not >used prof to find out whether the goto really resulted in faster >execution. He had, however, succeeded in making the code extremely >difficult to read. Goto, as implemented in an IBM PC compiler, may not be as efficient in some memory models as the equivalent code without goto's (because a jump across segments might be necessary). However, goto's can be much more efficient when all that is needed is a single assembler instruction to implement the goto (I oughta know: I had to implement this in an Ada-subset compiler for a graduate compiler course). >As for the example that was part of this original posting, the author >should learn to use the switch statement. The switch in C is in effect >a "conditonal goto" (to use the jargon I learned with the 1604 in >1968), but it is much, much easier to read. The _switch_ statement is a "conditional goto," but only for constants. Much better is the (cond ...) conditional statement in Lisp, or the _case_ statement in Ada. There are many times when I wish C would allow variables (and not just constants) after the _case_ keywords! >Since my specialty is Japanese history (albeit built on an undergrad >education in EE), I probably should not be telling >!!!!!PROGRAMMERS!!!!! (bells, gongs, drum rolls, trumpet flourishes) >how to do their work. You seem to have more experience writing code than many "programmers," and your comments are good. However, I still maintain that there are some cases where good use of a goto can make code much more "readable," and can save a helluva lot of additional tests that shouldn't be necessary. As long as it is not abused, _goto_ and setjmp()/longjmp() can be very useful. >Based on substantial experience, I would >nevertheless suggest that if you are absolutely convinced of the need >for a goto, that section of the code should really be done in >assembler. Talk about making the code unreadable by using a _goto_! Including assembler in a C program will really make it unreadable.-- Christopher Lishka ...!{rutgers|ucbvax|...}!uwvax!uwslh!lishka Wisconsin State Lab of Hygiene lishka%uwslh.uucp@cs.wisc.edu Immunology Section (608)262-1617 lishka@uwslh.uucp "I'm not aware of too many things... I know what I know if you know what I mean" -- Edie Brickell & New Bohemians