Xref: utzoo comp.lang.c:9420 comp.lang.misc:1452 Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!decwrl!ucbvax!pasteur!ames!umd5!purdue!i.cc.purdue.edu!k.cc.purdue.edu!l.cc.purdue.edu!cik From: cik@l.cc.purdue.edu (Herman Rubin) Newsgroups: comp.lang.c,comp.lang.misc Subject: Re: gotos Message-ID: <751@l.cc.purdue.edu> Date: 16 Apr 88 13:02:37 GMT References: <1988Apr8.183815.3187@utzoo.uucp> <449@goofy.megatest.UUCP> <3470@bunker.UUCP> Organization: Purdue University Statistics Department Lines: 101 Summary: Some clarification of the problem is needed; do not replace simple goto code with slow avoidances. In article <3470@bunker.UUCP>, garys@bunker.UUCP (Gary M. Samuelson) writes: > In article <748@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: > > > >Here is a challenge to the denigrators of goto. > > I am not sure I qualify, absolutely, but how about: > > Case 5: b >>= g16; > m |= b; > x = *(--geom); > if (TEST) > { > if(ODD(x)) > Case2(); > else > Case1(); > } > else > { > g4 = (x+1)/2; > if(ODD(x)) > Case3(); > else > Case4(); > } > > Readability improved through indentation at no extra charge. > Extraneous semi-colons tossed also. And, yes, I normally do > such things when I have to deal with ugly code. > > Now give me something hard. > > Gary Samuelson --For those who have not seen the original posting, replace Casej() by goto Casej. --------- I have no qualms with using or not using indentations. Also I think that the initial use of semi-colons by C was a mistake, and rather than getting obscure error messages, I admit I use too many. Now to the main point. I stated that this was a _fragment_ of code. After leaving Case5, this part of the code is not reached again until entered in the generation of a new item. That is, after going to one of the other cases, this block of code is _not_ to be returned to. Also, the cost of a subroutine call is huge compared with the cost of a goto. One of those responding by mail correctly deduced the original procedure, which can easily be written without gotos. The actual procedure as I would code it uses gotos even more, as it can be recognized that certain information may be in a reusable form. For example, instead of *(geom++) = z; in one case, followed by reading the item in the transferred case, just goto the intermediate step. The idea of the whole section of code, in a non-goto format, with most of the details omitted, as follows: (Please ignore C grammatical errors.) {if(w==3) {i=3; g4=1; break} else if (EVEN(w)){....} else if(w==5)ABORT; else .....} while(i>1) {switch(i) case 2: b >>= *(--geom); m |= b; i=1; break; case 3: (details omitted) case 4: (details omitted) case 5: as in the posted code, except goto Casej is replaced by i = j; break; case 6: (details omitted) case 7: (details omitted) default: (details omitted)} termination code (details omitted) A simple analysis of the instructions generated shows that much of the time is spent in storing the value of i (even if you can get your compiler to put it into a register) and carrying out the switch comparisons. In addition, there are many ways to combine operations using the structure of the code, and knowledge of the algorithm, to eliminate unnecesary transfers. The goto-less code has at least twice as many machine goto instructions as the goto code for the transfers to casej, and each there is an additional comparison instruction for each case move. I deliberately eliminated the storage of i for i<8. When your optimizing compiler can convert case switches with case numbers generated into the more efficient code such as I would write, I will consider eliminating those gotos. Alternatively, those features may be added to the language. However, I cannot see how even the most brilliant optimizing compiler could see some of the other uses of goto in the algorithm. There seems to be far more that the algorithm producer can think of than the language designer realizes is pos