henry@utzoo.uucp (Henry Spencer) (04/06/88)
> Sometimes, gotos are perfectly justifiable because they vastly > simplify and clarify you code. And once in a long while, there is no better way. A loooong while. If I were running a software house, I'd be tempted to say that using a goto -- except in fixing a program that already uses them -- means having $50 docked from your pay. It's not *forbidden*, you understand, it's just that you have to want it really badly! -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
djones@megatest.UUCP (Dave Jones) (04/07/88)
in article <1988Apr5.213343.1528@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) says: > ... > If I were running a software house, I'd be tempted to say that using > a goto -- except in fixing a program that already uses them -- means > having $50 docked from your pay. > HAHAHAHAHAHAHAHAHHAHHAHAHAHAHHAHAHHAHAHAHAHAHHAHAHAHAHHAHAHAHAHA. Try to pull that around here, and you'd be in the pond in about ten minutes flat. NOW. The first volley has been fired. May the goto-wars resume! Dave (Do Not Pass Go) Jones
nevin1@ihlpf.ATT.COM (00704a-Liber) (04/07/88)
In article <1988Apr5.213343.1528@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >And once in a long while, there is no better way. A loooong while. Agreed. Although I feel that most of the uses of GOTO in C these days occurs in the output of something like LEX and YACC, where I really don't mind it. Just as long as 'mere mortals' try to avoid using it. >If I were running a software house, I'd be tempted to say that using >a goto -- except in fixing a program that already uses them -- means >having $50 docked from your pay. It's not *forbidden*, you understand, >it's just that you have to want it really badly! Can I work for you?? I mean, if you would deduct $50 from my pay every time I use GOTO, I would rather spend the *over*time and write code that avoids it! :-) -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
levy@ttrdc.UUCP (Daniel R. Levy) (04/08/88)
In article <4307@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes: > In article <1988Apr5.213343.1528@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: > > >And once in a long while, there is no better way. A loooong while. > > Agreed. Although I feel that most of the uses of GOTO in C these days > occurs in the output of something like LEX and YACC, where I really don't > mind it. Just as long as 'mere mortals' try to avoid using it. I know this battle is an old chestnut, but for the record do you guys believe that superfluous flags and great big if-then statements are truly superior to the goto? (And the break, which is a goto by another name.) E.g.: while (loopcond) { for (i=0; i<limit; i++) if (frob(i) == TRUE) goto loopagain; /* nice and CLEAN!!! */ ... /* lots and lots of code over many pages */ ... loopagain: ; } versus while (loopcond) { boolean_flag=FALSE; for (i=0; i<limit; i++) { if (boolean_flag == TRUE) { ; /* spin uselessly */ } else if (frob(i) == TRUE) { boolean_flag=TRUE; } } if (boolean_flag==FALSE) { ... /* lots and lots of code over many pages */ ... } } -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (04/08/88)
In article <2556@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: > [...] >I know this battle is an old chestnut, but for the record do you guys believe >that superfluous flags and great big if-then statements are truly superior >to the goto? (And the break, which is a goto by another name.) E.g.: But... the break (and continue) are not the same as a goto. The goto transfers control to a label, which may be anywhere in the program. The break transfers control out of a loop. a) you know what it does when you write it b) you know what it does when you read it c) you won't move the stupid label or put code before it which should be after. I maintain that the evil is not the goto but the label. It can be put in the wrong place to start, and often during program changes gets moved, or statements inserted on the wrong side of it. I don't contend that it's EVIL, just that it is inherently a higher overhead to write and maintain then break and continue. Yes, I have used a few gotos, but always examine the logic before I do it. No, I don't think that longjmp() is a solution. -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs | seismo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
cramer@optilink.UUCP (Clayton Cramer) (04/09/88)
> > Sometimes, gotos are perfectly justifiable because they vastly > > simplify and clarify you code. > > And once in a long while, there is no better way. A loooong while. > If I were running a software house, I'd be tempted to say that using > a goto -- except in fixing a program that already uses them -- means > having $50 docked from your pay. It's not *forbidden*, you understand, > it's just that you have to want it really badly! > -- > "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology > non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry Exactly the right approach. The last project I supervised, the engineers that worked for me would occasionally try to justify a goto. Every single time, I demonstrated that the worst they were out was an automatic variable and maybe a do...while construct -- usually the do...while loop and an appropriate automatic variable were already there. I accept the remote possibility that goto might be appropriate somewhere -- just as I accept the remote possibility that leprechauns exist, and we've just never found them. Clayton E. Cramer
henry@utzoo.uucp (Henry Spencer) (04/09/88)
> Try to pull that around here, and you'd be in the pond in about ten > minutes flat. Remind me never to buy any software from you guys! -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
nevin1@ihlpf.ATT.COM (00704a-Liber) (04/09/88)
In article <2556@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: |I know this battle is an old chestnut, but for the record do you guys believe |that superfluous flags and great big if-then statements are truly superior |to the goto? (And the break, which is a goto by another name.) E.g.: | | while (loopcond) { | for (i=0; i<limit; i++) | if (frob(i) == TRUE) | goto loopagain; /* nice and CLEAN!!! */ | ... | /* lots and lots of code over many pages */ | ... |loopagain: ; | } Opinion: this is an example of FORTRAN disguised as C. |versus | while (loopcond) { | boolean_flag=FALSE; | for (i=0; i<limit; i++) { | if (boolean_flag == TRUE) { | ; /* spin uselessly */ | } else if (frob(i) == TRUE) { | boolean_flag=TRUE; | } | } | if (boolean_flag==FALSE) { | ... | /* lots and lots of code over many pages */ | ... | } | } Opinion: this is an example of Pascal disguised as C. For the record: these are BOTH bad C programming paradigms!! There are other constructs which can alter the flow of control: break, continue, and return. Use them!! In this particular case, using a continue statement inside in your Fortran-type example instead of a goto is much more preferable. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
djones@megatest.UUCP (Dave Jones) (04/09/88)
in article <2556@ttrdc.UUCP>, levy@ttrdc.UUCP (Daniel R. Levy) says: > > In article <4307@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes: >> In article <1988Apr5.213343.1528@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >> >> >And once in a long while, there is no better way. A loooong while. >> >> Agreed. Although I feel that most of the uses of GOTO in C these days >> occurs in the output of something like LEX and YACC, where I really don't >> mind it. Just as long as 'mere mortals' try to avoid using it. > > I know this battle is an old chestnut, but for the record do you guys believe > that superfluous flags and great big if-then statements are truly superior > to the goto? Of course not. (I can't believe this is starting up again. [Giggle.]) For me, the hardest thing to handle is real long blocks. You know, the things delimited by curly braces: for(; foo = bar; bleep < blap) { /* a skillion lines of code omited. */ } It's SO hard to figure out where the darn thing starts and where it ends. And if their are "breaks" and "continues", yech. When that happens, in these long blocks, I would prefer a "done:" label at the end and "gotos" rather than "breaks". That way, I can at least search for the label. Maybe we shoud start a raging argument about whether long blocks are _considered_harmful_. Shouldn't be much argument there.
sullivan@vsi.UUCP (Michael T Sullivan) (04/09/88)
In article <2556@ttrdc.UUCP>, levy@ttrdc.UUCP (Daniel R. Levy) writes: > I know this battle is an old chestnut, but for the record do you guys believe > that superfluous flags and great big if-then statements are truly superior > to the goto? (And the break, which is a goto by another name.) E.g.: > > while (loopcond) { > for (i=0; i<limit; i++) > if (frob(i) == TRUE) > goto loopagain; /* nice and CLEAN!!! */ > ... > /* lots and lots of code over many pages */ > ... > loopagain: ; > } while (loopcond) { flag = FALSE; for (i=0; i<limit; i++) { if (frob(i)) { flag = TRUE; break; } } if (flag) continue; ... /* lots and lots of code over many pages */ ... } You don't have to spin your wheels in a for loop and you don't have to use the goto. I should think if you can avoid a goto, do it. Some people believe gotos are inherently not "nice and CLEAN!!!". But as you say, this is an old chestnut. -- Michael Sullivan {uunet|attmail}!vsi!sullivan sullivan@vsi.com HE V MTL
tainter@ihlpg.ATT.COM (Tainter) (04/09/88)
In article <4347@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes: > In article <2556@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: > |I know this battle is an old chestnut, but for the record do you guys believe > |that superfluous flags and great big if-then statements are truly superior > |to the goto? (And the break, which is a goto by another name.) E.g.: > | > | while (loopcond) { > | for (i=0; i<limit; i++) > | if (frob(i) == TRUE) > | goto loopagain; /* nice and CLEAN!!! */ > | .../* lots and lots of code over many pages */... > |loopagain: ; > | } > Opinion: this is an example of FORTRAN disguised as C. > In this particular case, using a continue statement > inside in your Fortran-type example instead of a goto is much more preferable. Except of course that that wouldn't work since it is nested under a second loop. This is the only alternative to using a flag on the lines of the alternative code. [ Flag riddled code at indentation >> removed ] > Opinion: this is an example of Pascal disguised as C. > _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 People, listen closely, GOTOs are not inherently bad. If used carefully as in this example they are quite reasonable and really not hard to follow. Of course, they would be much harder to understand if they didn't use mnemonics and instead used numbers ala Pascal or ForTran. --j.a.tainter
djones@megatest.UUCP (Dave Jones) (04/09/88)
in article <2009@optilink.UUCP>, cramer@optilink.UUCP (Clayton Cramer) says: > >> > Sometimes, gotos are perfectly justifiable because they vastly >> > simplify and clarify you code. >> >> And once in a long while, there is no better way. A loooong while. >> If I were running a software house, I'd be tempted to say that using >> a goto -- except in fixing a program that already uses them -- means >> having $50 docked from your pay. It's not *forbidden*, you understand, >> it's just that you have to want it really badly! >> -- >> "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology >> non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry > > Exactly the right approach. The last project I supervised, the engineers > that worked for me would occasionally try to justify a goto. Every single ^^^^^^ ^^^ ^^ > time, I demonstrated that the worst they were out was an automatic variable > and maybe a do...while construct -- usually the do...while loop and an > appropriate automatic variable were already there. > > I accept the remote possibility that goto might be appropriate somewhere -- > just as I accept the remote possibility that leprechauns exist, and we've > just never found them. > > Clayton E. Cramer ( As always, insert smilie faces after every line that irks you. I really don't take all of this too seriously. ) No no no. Threatening employees with punative fines is NOT the right approach. I find the idea repugnant. Blechh! I trust that Mr. Spenser meant only that he feels strongly that a goto is a no-no. I don't think he really meant that he has to bully his employees to get them to do it his way. He seems like a nice enough fellow. Texan, I think. Mr. Cramer says that he has always been able to show that adding an automatic variable and some extra tests can obviate the goto. Indeed 'tis true. There's a famous proof to that effect. Constructive proof. Of course the resulting code is harder to read than the original, but it's purged of those malicious communist-inspired gotos. The "come-from" problem of labels, as it has been called, is replaced by the "set-where" problem of SLB's (Silly Little Booleans). No improvement in my estimation. If it were, we could just run all of those evil programs through a filter that exorcises the daemon gotos, and leaves only morally correct transpicuous code. Sorry, it ain't that easy. I think Mr. Cramer will find that the readers of this group may not be quite so willing to agree that his code transformations improve their goto examples as his employees seem to be. I am honored to be entrusted with maintaining some of the hardest to read code you have ever seen. (Trust me on this one. It's true.) So I am something of an expert on how to write for obfuscation. I haven't been thrown by a goto yet. That's just control flow. Piece of cake. If you really want to scramble some heads, screw up the data structure definitions! One more thing. The way I see it, the supervisor works for the engineer, not the other way around. I'm about to embark on supervising a year-long project. We'll see if I still have that attitude next April. I can't believe this goto thing is starting all over again. Dave (finished = TRUE;) Jones
djones@megatest.UUCP (Dave Jones) (04/10/88)
in article <1988Apr8.183815.3187@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) says: > >> Try to pull that around here, and you'd be in the pond in about ten >> minutes flat. > > Remind me never to buy any software from you guys! > -- > "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology > non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry I fail to see any justification for such a remark. I think an appology is in order. Mr. Spenser is replying to my response about about managers fining employees for using a goto-statement. Dave Jones
henry@utzoo.uucp (Henry Spencer) (04/10/88)
> ... do you guys believe > that superfluous flags and great big if-then statements are truly superior > to the goto? ... Well, speaking only for myself, I believe that thought and organization are indeed truly superior to "hack it together somehow", and that the former approach seldom leads to gotos or "superfluous flags and great big if-then statements" -- or to the *desire* to use either. Don't confuse the symptoms with the underlying disease. The desire to use a goto is not an awful sinful thought that should be suppressed, it is a warning that you've goofed. The proper response is not to kludge around it, but to stand back and re-think the structure of the code. (In emergencies there may not be time for this, of course, but many things can be excused in an emergency... provided that you go back and clean up the mess afterward.) -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
henry@utzoo.uucp (Henry Spencer) (04/10/88)
> ... I don't think he really meant that he has to bully his employees to > get them to do it his way. Not a problem, since any who don't, don't stay employees :-). > He seems like a nice enough fellow. Texan, I think. Well, you got the longitude roughly right at least... Saskatchewanian. > ... The way I see it, the supervisor works for the > engineer, not the other way around. Real engineers work for themselves, not for their supervisors! -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
levy@ttrdc.UUCP (Daniel R. Levy) (04/10/88)
In article <5170@ihlpg.ATT.COM>, tainter@ihlpg.ATT.COM (Tainter) writes: # In article <4347@ihlpf.ATT.COM>, nevin1@ihlpf.ATT.COM (00704a-Liber) writes: # > In article <2556@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: # > |I know this battle is an old chestnut, but for the record do you guys believe # > |that superfluous flags and great big if-then statements are truly superior # > |to the goto? (And the break, which is a goto by another name.) E.g.: # > | while (loopcond) { # > | for (i=0; i<limit; i++) # > | if (frob(i) == TRUE) # > | goto loopagain; /* nice and CLEAN!!! */ # > | .../* lots and lots of code over many pages */... # > |loopagain: ; # > | } # > Opinion: this is an example of FORTRAN disguised as C. # > In this particular case, using a continue statement # > inside in your Fortran-type example instead of a goto is much more preferable. # # Except of course that that wouldn't work since it is nested under a second loop. # This is the only alternative to using a flag on the lines of the alternative # code. # [ Flag riddled code at indentation >> removed ] # > Opinion: this is an example of Pascal disguised as C. # > _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 # People, listen closely, GOTOs are not inherently bad. If used carefully # as in this example they are quite reasonable and really not hard to follow. # Of course, they would be much harder to understand if they didn't use # mnemonics and instead used numbers ala Pascal or ForTran. # --j.a.tainter Somebody mailed me a much better form of what I was trying to do: while (loopcond) { for (i=0; i<limit && frob(i)!=TRUE; i++) ; if (i<limit) continue; ... } This IS just as clean, just as fast, and doesn't involve any gotos. The picture gets muddier when you have multiple nested loops however: while (loopcond) { for (i=0; i<ilimit; i++) for (j=0; j<jlimit; j++) for (k=0; k<klimit; k++) if (frob(i,j,k)==TRUE) goto loopagain; /* lotsa code */ loopagain: ; } Getting out of this one without gotos requires continual testing of a flag in the for loops: /* look ma, no gotos! */ while (loopcond) { bustout=FALSE; for (i=0; i<ilimit && bustout==FALSE; i++) for (j=0; j<jlimit && bustout==FALSE; j++) for (k=0; k<klimit; k++) if (frob(i,j,k)==TRUE) { bustout=TRUE; break; } if (bustout==TRUE) continue; /* lotsa code */ } Trouble with this method is that you lose some performance. What's a hacker to do? :-) :-) :-) -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
decot@hpisod2.HP.COM (Dave Decot) (04/10/88)
> For me, the hardest thing to handle is real long blocks. You know, > the things delimited by curly braces: > > > for(; foo = bar; bleep < blap) > { > /* a skillion lines of code omited. */ > } > > It's SO hard to figure out where the darn thing starts and where it ends. > And if their are "breaks" and "continues", yech. When that happens, > in these long blocks, I would prefer a "done:" label at the end and > "gotos" rather than "breaks". That way, I can at least search for the label. > > Maybe we shoud start a raging argument about whether long blocks are > _considered_harmful_. Shouldn't be much argument there. Yes. The solution is not to introduce a label; it is to break up the long blocks into appropriate separate functions. Dave "I use gotos to get fully out of nested loops" Decot hpda!decot
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/10/88)
In article <449@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
-in article <1988Apr8.183815.3187@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) says:
->> Try to pull that around here, and you'd be in the pond in about ten
->> minutes flat.
-> Remind me never to buy any software from you guys!
-I fail to see any justification for such a remark. I think an appology
-is in order.
I don't agree. Henry is simply remarking that he doesn't have much
trust in software produced by people who take pride in using GOTOs.
That seems an eminently defensible position to me.
daveb@geac.UUCP (David Collier-Brown) (04/11/88)
In article <reference lost> djones@megatest.UUCP (Dave Jones) writes: >>> Try to pull that around here, and you'd be in the pond in about ten >>> minutes flat. In article <1988Apr8.183815.3187@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) says: >> Remind me never to buy any software from you guys! In article <449@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >I fail to see any justification for such a remark. I think an appology [sic] >is in order. Quite the contrary: you owe Mr. Spenser an apology for whining: It is not good form to complain when someone points out you've admitted in a **public forum** your willingness to enshrine known bad practice. For shame! --dave (I use goto's && Henry can fine me) c-b -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
henry@utzoo.uucp (Henry Spencer) (04/12/88)
> >> Try to pull that around here, and you'd be in the pond in about ten > >> minutes flat. > > > Remind me never to buy any software from you guys! > > I fail to see any justification for such a remark. I think an appology > is in order. Sorry, I consider the remark well-justified and will not apologize. If you read my other postings on the subject, you will see that I consider the use of gotos, especially the frequent use of gotos, to be a sign of poor organization and "coding before thinking". Given this opinion, it is hardly surprising that I would be reluctant to buy software from an organization which endorses routine use of gotos. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
al@gtx.com (0732) (04/12/88)
->to the goto? (And the break, which is a goto by another name.) E.g.: a quibble here. a break is a "goto by another name" as much as a while loop is a "goto by another name". In fact a break is a considerably restricted form of a goto, and it is this restriction that makes it easier to read and understand, and not at all comparable to those awful unrestricted goto's. By the way, this discussion reminds me of a letter that appeared a few years ago in CACM. ,It was from a man in Japan named Mr. Goto, and it was a complaint about how everyone was always trying to eliminate him. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ( Alan Filipski, GTX Corp, 8836 N. 23rd Avenue, Phoenix, Arizona 85021, USA ) ( {ihnp4,cbosgd,decvax,hplabs,amdahl,nsc}!sun!sunburn!gtx!al (602)870-1696 ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mick@auspyr.UUCP (Michael J. Andrew) (04/12/88)
In article <1988Apr5.213343.1528@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >> Sometimes, gotos are perfectly justifiable because they vastly >> simplify and clarify you code. > >And once in a long while, there is no better way. A loooong while. >If I were running a software house, I'd be tempted to say that using >a goto -- except in fixing a program that already uses them -- means >having $50 docked from your pay. It's not *forbidden*, you understand, >it's just that you have to want it really badly! This is a excellent extension to a scheme I keep proposing half- seriously to management, to encourage good programming practices among novice, sloppy or lazy programmers. Provide each member of the team a $500 bonus at the start of a new project, but deduct $50 each time a global variable is introduced into the design. Wh -- ------------------------------------------------------------------------- Michael Andrew Sr. Systems Engineer Austec, Inc. San Jose CA. mick@aussjo.UUCP (408) 279 5533
cik@l.cc.purdue.edu (Herman Rubin) (04/12/88)
Here is a challenge to the denigrators of goto. I present a short fragment of code; this code should be modified if right shifts are negative left shifts, but the problems are the same. Case 5: b >>= g16; m |= b; x = *(--geom); if (TEST) {if(ODD(x)) goto Case2; else goto Case1;}; else {g4 = (x+1)/2; if(ODD(x)) goto Case3; else goto Case4;}; I claim that this construction is easily understood, except possibly by those who are anti goto, and is efficient code. TEST involves a random bit, and geom is a pointer to a random quantity, so that one can not anticipate the values. Also each of the Cases 1-4 are more likely to be reached in other ways than from Case 5. How else would you do it? -- Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/13/88)
> > Case 5: b >>= g16; > m |= b; > x = *(--geom); > if (TEST) > {if(ODD(x)) goto Case2; else goto Case1;}; > else {g4 = (x+1)/2; if(ODD(x)) goto Case3; else goto Case4;}; > .... > Also each of the Cases 1-4 are more likely to be reached in other > ways than from Case 5. > > How else would you do it? FUNCTIONS!!!! -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
djones@megatest.UUCP (Dave Jones) (04/13/88)
in article <1988Apr11.201934.20594@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) says: > >> >> Try to pull that around here, and you'd be in the pond in about ten >> >> minutes flat. >> >> > Remind me never to buy any software from you guys! >> >> I fail to see any justification for such a remark. I think an apology >> is in order. > > Sorry, I consider the remark well-justified and will not apologize. If > you read my other postings on the subject, you will see that I consider > the use of gotos, especially the frequent use of gotos, to be a sign of > poor organization and "coding before thinking". Given this opinion, it > is hardly surprising that I would be reluctant to buy software from an > organization which endorses routine use of gotos. > -- > "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology > non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry I should not say any more about this, but I can not restrain myself. My flip remark about the dousing of stuffed shirts was ill judged. In my defense, let me say that it never occurred to me that Mr. Spencer was serious about fining employees for using a goto statement. I incorrectly thought that I was continuing a joke which he had started. I did make the postings in good faith, in the sincere expectation of casting some light on a subject which reappears in the group from time to time. Unlike the redoubtable Mr. Spencer, I do not pretend to make judgemental pronouncements about the quality of thought of those who use or do not use an occasional goto. But I feel that my seventeen years of experience programming, and my experiences a university computer science professor give me some perspective, if nothing else. Mr Spencer, Mr. David Brown, and the loquacious Mr. Gwyn all say straight out that I am an advocate of the use of the goto statement. But I never once in any of my postings endorsed the use of the goto statement! You may verify as much if you will reread the postings. (In one posting I said that if I have to read long long blocks, I would prefer that they be exited by a goto rather than a "break", simply because it's easier to find the label than it is to find the closing curly brace. This "lesser of two evils" is hardly an endorsement.) I only stated that the importance which some people place on avoiding the gotos is exceedingly exaggerated, and that time spent campaigning against its use is misspent. This is an opinion which I still hold. But all this is quite incidental. Mr. Spencer is entitled to his opinions about programming techniques, as am I. I objected not to Mr. Spencer's mistaken reading of my postings. I objected to his affrontary. You three, Spencer, Brown, and Gwyn, hold that it is proper for you to publicly criticize the software produced by the company which employs me, on the basis of a few lines that I wrote here. To presume that you are competent to judge products you have never used is ridiculous. To presume to make such pronouncements publicly is, by my values, rude at best. Perhaps I should only say that we have differing values not only about some small software engineering matters, but also about what constitutes good manners and acceptable behavior. I find this whole matter very distasteful. I regret having provoked it. I'm through with comp.lang.c for a while.
levy@ttrdc.UUCP (Daniel R. Levy) (04/13/88)
In article <1988Apr11.201934.20594@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > > >> Try to pull that around here, and you'd be in the pond in about ten > > >> minutes flat. > > > > > Remind me never to buy any software from you guys! > > > > I fail to see any justification for such a remark. I think an appology > > is in order. > > Sorry, I consider the remark well-justified and will not apologize. If > you read my other postings on the subject, you will see that I consider > the use of gotos, especially the frequent use of gotos, to be a sign of > poor organization and "coding before thinking". Given this opinion, it > is hardly surprising that I would be reluctant to buy software from an > organization which endorses routine use of gotos. You darn well know, if you'd take off your elitist blinders, that the use of gotos is not an INFALLIBLE sign of "poor organization and 'coding before thinking'". Indeed it could well be that Dave Jones and his buddies at Megatest, in spite of their gotos, may produce code with more functionality, fewer bugs, and better support than you do, but you'd never know it if you won't give them a chance to show it. Gotos are only one metric of style, in sparse use only weakly related to functionality and bugproofness, and to declare code that uses them anathema as a matter of broad policy is like using the Whetstone as your sole criterion for purchasing a computer. It makes a lot more sense to judge a software producer on their reputation for other software they have produced, than to judge them on a tiny aspect of coding style. There are just too many other variables. If you are ever in a position to purchase Megatest's (or any other company's) software, ask around about how well that company's software (not just the package in question) has worked in the past and how well it is supported. Any other criterion of quality is pure conjecture. -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (04/13/88)
In article <451@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes: > I find this whole matter very distasteful. I regret having provoked it. > > I'm through with comp.lang.c for a while. Please, please, please don't go :-). Seriously Dave, don't let it get to you. No matter what you do on this net, you're bound to piss someone off eventually. Hell, I've been exclaimed, I've been ignored and I've been flamed - I should know. My attitude has always been to learn from my mistake or at least try to understand the other persons perspective. In doing so I've learned alot and I'm thankful for that. In your case, you'll just have to understand that there are people that have very strong feelings about the use goto. I advised you to at least consider what they have to say. BTW: I would have mailed to you directly but there's no return mailing path in you signature. -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
dhesi@bsu-cs.UUCP (Rahul Dhesi) (04/14/88)
In article <451@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >I only stated that the importance which some people place >on avoiding the gotos is exceedingly exaggerated, and that time spent >campaigning against its use is misspent. This is indeed very true. It is not always wise to simply criticize gotos instead of asking why a goto was necessary. It could be lousy algorithm design or, more commonly than you think, less-than-perfect programming language design. Some things are best done with a goto! And I know of no language, with the possible exception of Ada, that is rich enough in control structures to always have an elegant and efficient alternative to using a goto. The best collection of thoughts I have seen on this issue is by Donald Knuth, entitled "Structured Programming with goto Statements", originally published in one of the ACM journals (probably Computing Surveys) circa 1974 and republished by Prentice Hall in 1977 in "Current Trends in Programming Methodology" volume I, edited by Raymond T. Yeh. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee,uunet}!bsu-cs!dhesi
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/14/88)
In article <451@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >Mr Spencer, Mr. David Brown, and the loquacious Mr. Gwyn all say straight >out that I am an advocate of the use of the goto statement. There you go, putting (wrong) words in other peoples' mouths. >You three, Spencer, Brown, and Gwyn, hold that it is proper for you to >publicly criticize the software produced by the company which employs me, >on the basis of a few lines that I wrote here. Ditto. I merely maintained that it is appropriate for Henry to think poorly of a company that publicly announces its liberal use of GOTO with apparent pride. If that's not what you intended to do, then Henry and I must have misunderstood you. I use GOTO myself, but only in a disciplined way and only when there are sound technical reasons for so doing. (Branching to a common section of error-recovery code at the end of a function body is the most usual situation.) But I'm not going to wear a lapel pin that proclaims "I USE GOTOS"! My, how touchy people get when they think that money is involved.
levy@ttrdc.UUCP (Daniel R. Levy) (04/14/88)
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 present a short fragment of # code; this code should be modified if right shifts are negative left shifts, # but the problems are the same. # # Case 5: b >>= g16; # m |= b; # x = *(--geom); # if (TEST) # {if(ODD(x)) goto Case2; else goto Case1;}; # else {g4 = (x+1)/2; if(ODD(x)) goto Case3; else goto Case4;}; Gak, what IS this? Where are the Case[1-4] labels even? This IS raunchy code. (Are you trying to hand-code a state machine?) -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
root@mfci.UUCP (SuperUser) (04/14/88)
Expires: Sender: Followup-To: Distribution: Keywords: I feel that taking a near religious stance on the prohibition of something like goto is a mistake, although I can understand why people are tempted. Few would argue that the proper use of functions, compound statements, and flow control statements isn't preferable to long rambling routines whose control structures resemble a tangled ball of fishing line. Avoiding the use of gotos is probably a good rule of thumb for beginning programmers or programmers who have only used languages like Basic or Fortran, to get them used to the fact that they can do just about anything without using gotos and without contorting their program structure (avoiding gotos usually improves program structure). However, the most important goals in writing code are that it functions properly, that it is clearly written and maintainable, and that it is reasonably efficient. Of course, there may sometimes be a tradeoff between the last two goals, but in many cases where a goto may be appropriate it is often in the interests of both these goals. The most common place where the use of a goto is not inappropriate in C is when it is used to exit multiple levels of nested loops or other such control structures. Some languages permit constructs such as "break n" to accomplish this, but I generally consider this sort of practice to be bad, because it is painful to maintain. I.e., if you wanted to wrap it in a loop, or remove a loop from around it, you would have to delve into the code to alter the "level" of the break. I prefer to achieve the effect of a the LEAVE expression of Bliss. This is a STRUCTURED construct, in that it cannot be used to create irreducible flow graphs (all Bliss flow graphs are reducible). It can only be used to exit an expression from anywhere within the expression, and is no different from returning from a routine within a loop, except that you are merely exiting from a statement rather than the entire routine. In C, the same effect can be achieved by placing a label right after a loop, then branching to the label from within one or more nested loops. The resulting flow graph is still reducible, and avoids the use of flow control flags, which almost always obscure the code, and often slow it down as well. (This isn't to say that I think flow control flags are always inappropriate, but in most typical cases it is preferable to replace them with explicit exits, via goto.) Many other uses of goto are probably best avoided, such as branching into loops. Often the need to branch into a loop arises because the loop is naturally a "mid-tested" loop, in which case it can be rewritten as a for(;;) { ... } loop, with an explicit exit test in the middle. In cases where the loop really has multiple entry points, it is up to the implementor to decide whether it can be restructured to avoid the problem, or whether it's worth explicitly adjusting the various cases before the loop so they can all enter at the same point, or whether it's worth entirely replicating the loop, etc. However, people should realize that if their code incorporates irreducible loops, their compiler may not do a good job of optimizing it. I have seen rare examples where an irreducible loop is the clearest way to code something, although even in those cases it is usually preferable to avoid them. However, I would not go so far as to say they are 100% wrong and should NEVER be used. For example, I have seen people implement small state machines with gotos, where each state explicity branches to the next state, rather than having to go through the overhead of a switch statement at the top of an outer loop. This can be useful in small, simple lexical analyzers. True, keeping the state in a variable which is used in a switch statement probably isn't that much slower, and could even be faster in some cases (if the compiler does a better job of optimizing reducible loops), but nevertheless it may not always be the best choice. The other case I can think of where a goto might be appropriate is if you have a complicated loop which is making some determination about something, and at various points in the loop it may "accept" or "reject" something, in which case you'd like to go to some common piece of code to perform the necessary bookkeeping. Ideally the loop would be contained in a routine which simply returns true or false and leaves it up to the caller to take whatever action is appropriate, but again this may not always be practical. In this case I would argue that the code being branched to should be placed outside of the code that branches to it (rather than coding it as the consequent of one test and then branching to it from the others). However, the end of it should not turn around and branch back into a loop or whatever, but should instead return from the routine or fall through to the bottom of a loop or to some ordinary sequential code which follows it, etc. All this isn't meant to imply that I like gotos and that they don't bother me. I very rarely use them, and in cases where I do it is because I have carefully investigated the alternatives and been unable to eliminate them without compromising the control structure of my code in even less desirable ways. Nevertheless, if used with restraint they do have their places.
daveb@geac.UUCP (David Collier-Brown) (04/14/88)
In article <1988Apr11.201934.20594@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > Remind me never to buy any software from you guys! In article <2575@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >You darn well know, if you'd take off your elitist blinders, that... Gentlemen! Look back at the discussion to date before throwing assuming Henry's being nasty: he was defending a proposal to charge $50.00 per goto, to discourage misuse. The other gentleman was threatening to throw him in the duckpond (:-). This was a good-natured, if spirited, debate. I like the $50.00 scheme, actually, although I do use gotos[1]. I figure it (the $50.00) is a good example of making engineering tradeoffs explicit. --dave (a philosopher on the engineering faculty council...) c-b [1] In time-critical inner loops to avoid returns, typically. See Knuth "Structured Programming with Go To Statements". -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
levy@ttrdc.UUCP (Daniel R. Levy) (04/14/88)
In article <7681@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: # In article <451@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: # >Mr Spencer, Mr. David Brown, and the loquacious Mr. Gwyn all say straight # >out that I am an advocate of the use of the goto statement. # # There you go, putting (wrong) words in other peoples' mouths. # # >You three, Spencer, Brown, and Gwyn, hold that it is proper for you to # >publicly criticize the software produced by the company which employs me, # >on the basis of a few lines that I wrote here. # # Ditto. I merely maintained that it is appropriate for Henry to # think poorly of a company that publicly announces its liberal use # of GOTO with apparent pride. If that's not what you intended to do, # then Henry and I must have misunderstood you. Begging your pardon, unless Dave posted an article I never saw, the strongest thing he ever said which would tend to lead one to believe his company liberally uses GOTO was something to the effect that "You'd get laughed into the pond in ten minutes if you tried that here" [pay-docking mind games to sear the fear of GOTO into every programmer's heart]. From what I see, Spencer especially took that as a endorsement of liberal use of GOTO at Megatest. (And even I went along with that notion [viz. an earlier posting of mine saying "so what if he does use lots of GOTOs? that's not the only valid metric of code"] till I looked more carefully at what was actually being said.) YOU should talk about putting "(wrong)" words into other peoples' mouths! (Or wrong thoughts into other people's heads, or wrong lines into other peoples' code.) -- |------------Dan Levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an Engihacker @ | <most AT&T machines>}!ttrdc!ttrda!levy | AT&T Data Systems Group | Disclaimer? Huh? What disclaimer??? |--------Skokie, Illinois--------|
daveb@geac.UUCP (David Collier-Brown) (04/14/88)
Before sending that last-referenced message, I admit to have launched a flame. Sorry! I cancelled it. You shouldn't get it. If you do, ignore it. If you can't ignore it, send mail to my boss. --dave (I gotta pay more attention to what's said, not how) c-b -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/15/88)
In article <2586@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: >Spencer especially took that as a endorsement of liberal use of GOTO at >Megatest. That was also the impression I got when I read the same posting. That doesn't mean that it was intended to convey that impression, but as we should all well know by now it is easy to be misinterpreted. I don't think I have accused that company of shoddy workmanship or urged boycotting its products. I've been defending Henry's right to draw such conclusions for himself. It was rather tactless to post those conclusions publicly, but originally I don't think Henry was really urging a product boycott either, just remarking on what he thought the likely effect on product quality would be from what he perceived as the corporate attitude. I'm glad to hear that that company (whose name I don't recall) is not committed to indiscriminate use of GOTO. I also agree with those who say that GOTO use is not the only measure of software merit. Now, can we please stop misunderstanding each other and get back to squabbling about TECHNICAL issues?
campbell@maynard.BSW.COM (Larry Campbell) (04/15/88)
In article <2618@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
<>...And I know of no language, with the possible exception of Ada, that is
<>rich enough in control structures to always have an elegant and
<>efficient alternative to using a goto.
Check out BLISS. It's not without its flaws -- I consider its extreme
typelessness a botch -- but it has such a complete set of well thought
out control constructs that you don't miss the goto at all. (BLISS has
no goto.)
--
Larry Campbell The Boston Software Works, Inc.
Internet: campbell@maynard.bsw.com 120 Fulton Street, Boston MA 02109
uucp: {husc6,mirror,think}!maynard!campbell +1 617 367 6846
henry@utzoo.uucp (Henry Spencer) (04/16/88)
> The best collection of thoughts I have seen on this issue is by Donald > Knuth, entitled "Structured Programming with goto Statements"... The amusing thing about Knuth's article is that when you subtract out the search loops (which can be handled with break or return), the syntax example (which can be done *much* more elegantly using ungetc()), and the things that any modern compiler (NB the 4BSD VAX compiler is an antique) would look after for you... there's nothing left! Also left as an exercise for the reader is finding the bug in Knuth's hash-table-search code. (He might possibly have corrected this in the reprint; my copy is the original Computing Surveys paper.) The hazards of gotos doth make fools of the best of us... -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {allegra,ihnp4,decvax,utai}!utzoo!henry
nevin1@ihlpf.ATT.COM (00704a-Liber) (04/16/88)
First off Herman, I want to thank you for giving an example of why GOTO's should NOT be used indiscriminately! 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 present a short fragment of >code; this code should be modified if right shifts are negative left shifts, >but the problems are the same. >Case 5: b >>= g16; > m |= b; > x = *(--geom); > if (TEST) > {if(ODD(x)) goto Case2; else goto Case1;}; > else {g4 = (x+1)/2; if(ODD(x)) goto Case3; else goto Case4;}; You should enter the whole program in the Obfuscated C contest! As long as it's under 1536 characters, it's sure to win!! :-) If you can't enter it, wait for the BASIC-disguised-as-C Contest! :-) >I claim that this construction is easily understood, except possibly by those >who are anti goto, and is efficient code. TEST involves a random bit, and >geom is a pointer to a random quantity, so that one can not anticipate the >values. Also each of the Cases 1-4 are more likely to be reached in other >ways than from Case 5. I cannot, simply by looking at it, tell what it's supposed to do. 60% or more of the work of programming should go into design and NOT coding, as it seems like it was done here. >How else would you do it? I don't know. If I had a good design spec of what the *whole* program is supposed to do I could probably write it in a C-like readable fashion without using a single GOTO. But don't expect me to rewrite a code fragment which is obviously totally dependent on GOTOs. Off the subject: For those of you who don't read comp.lang.misc: Herman has claimed that he can write a much better language than anything we have now, provided he can find someone to write the compiler for him. I, among others, have volunteered my time to help him on his quest and we are waiting for him to finish his *formal* detailed description of the language. So please don't bother him until *after* he completes this historical document. He's keeping the whole world on hold!! -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
garys@bunker.UUCP (Gary M. Samuelson) (04/16/88)
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
nevin1@ihlpf.ATT.COM (00704a-Liber) (04/16/88)
In article <2581@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes: > I like the $50.00 scheme, actually, although I do use gotos[1]. >I figure it (the $50.00) is a good example of making engineering >tradeoffs explicit. I don't like the scheme, because I would rather find a way around using GOTO than pay the $50. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) "The secret compartment of my ring I fill / / _ , __o ____ with an Underdog super-energy pill." / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
cik@l.cc.purdue.edu (Herman Rubin) (04/16/88)
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
henry@utzoo.uucp (Henry Spencer) (04/17/88)
> You darn well know, if you'd take off your elitist blinders, that the use > of gotos is not an INFALLIBLE sign of "poor organization and 'coding before > thinking'"... Oh, I'll concede the possibility. But I've never found a clear example in code that I've either (a) written, or (b) analyzed thoroughly. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
henry@utzoo.uucp (Henry Spencer) (04/17/88)
> <>...And I know of no language, with the possible exception of Ada, that is > <>rich enough in control structures to always have an elegant and > <>efficient alternative to using a goto. > > Check out BLISS... Don't forget the Unix shell. (The standard one, not the silly thing from Berkeley.) -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
peter@athena.mit.edu (Peter J Desnoyers) (04/17/88)
In article <751@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: >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. I don't know about optimizing compilers, but I've heard horror stories of non-optimizing compilers using jumptables for switch statements. (Oh no!! Why does "switch (n) {case 0: foo(); case 20000: bar();}" generate an 80k executable?) It may have been an older VMS compiler. I dunno... Personally, I think that doing such grevious harm to the source code in the name of 'optimizing' is off the mark. The time spent writing and maintaining that code could have been spent (1) buying an optimizing compiler; (2) writing it in assembler; or (3) convincing your boss to spring for a faster machine. Perhaps a better thing than docking people's pay for 'goto's would be a compiler that put a delay in with every goto. Ten or twenty nop's should be about right. Then people would only use goto when it was really needed for stylistic reasons. btw, my favorite reason for using goto - to cope with the problem that the same word (break) is used to terminate loops and to signal the end of a section of a switch. Thus you can write "if (foo) break;", but you may have reason to write: (what you want to write: ) while (foo) while (foo) switch (bar) switch (bar) { { case n: case n: goto (end_while); break; break; esac; /* or whatever */ } } end_while: Peter Desnoyers peter@athena.mit.edu
ajmyrvold@violet.waterloo.edu (Alan Myrvold) (04/17/88)
Why do I use goto's ? Because I believe that every function should have exactly one entry point and exactly one exit point. Multiple RETURN statements are as bad as bad goto's -- i.e. the thread of the subroutine gets confusing. I only have labels at the end of my functions, and yes the real problem with neat code with goto's is that it is soooo easy for someone else to start inserting code on the wrong side of the goto. But don't dock my pay for eliminating RETURN statements that are scattered through a subroutine. :-) ------------------------------------------------------------------- Si je t'aime? Bien sur que je t'aime! Ne suis-je pas en train de te le prouver encore une fois, dans ce lit? ------------------------------------------------------------------- Alan Myrvold ajmyrvold@violet.waterloo.edu -------------------------------------------------------------------
purtill@faline.bellcore.com (Mark Purtill) (04/18/88)
In article <> ajmyrvold@violet.waterloo.edu (Alan Myrvold) writes: >Why do I use goto's ? > >Because I believe that every function should have >exactly one entry point and exactly one exit point. > >Multiple RETURN statements are as bad as bad goto's -- i.e. >the thread of the subroutine gets confusing. First off, I find this claim dubious to say the least, especially if many returns are error returns (eg: char * get_foo( char *filename) { /* returns the foo or NULL on error */ ... if(( fp = fopen( filename, mode)) == NULL) { return (char *)NULL ; } ... if( syntax error in the foo) return (char *)NULL ; ... return foo ; } ). In any case, I fail to see how replacing a "return" with a "goto" will make it any less confusing, especially given that the label for the goto may be on the next page, or that the next person to deal with the code may add code after the label, etc. All you've done is replace earlier "return"s with "goto label"s which may not really do what you want. ^.-.^ Mark Purtill ((")) purtill@math.mit.edu
mcdonald@uxe.cso.uiuc.edu (04/18/88)
Why use goto's? Simple: because it makes sense in the context of the problem at hand. FLAME ON ... TEMPERATURE 100,000,000 degress !!! 1e28 tons of helium ready to turn into Nickel56!!!!!!! (ask sci.astro) I am FED UP with goto bashers! I'll admit that code filled with gotos may be messy: if I write a goto, it's because I feel like it! I don't give a DAMN whether you like goto's or not; I believe in using whatever tool is at hand to get the job done. I frankly don't believe for ONE CLOCK TICK OF A CRAY 2 that gotos make code worse. Spaghetti is spaghetti, whether it is done with gotos or some other construct, and so is any other equivalent mess. But keep up the battle; I'll agree it is worth a good chuckle. Doug McDonald Professor of Chemistry University of Illinois
daveb@laidbak.UUCP (Dave Burton) (04/18/88)
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. |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(); | } Gary - this is no flame in your direction (Herman deserves all he receives for writing code like he challenged with). With the type of logic the original code fragment was using, your modification would be deep down in nested and re-nested function calls before you could say "Memory fault -- core dumped" :-). About the only way (from the too little context given by Herman) that I know to clean up his code without gotos is to use states. The overhead is very small, typically just one extra test per 'loop'. Maybe something like: enum calcs { start, state0, ..., state5 } state = start; enum calcs compute(); switch (state) { case start: state = compute(); break; case state0: x = 1+2; state = CRAP(x) ? state1 : state2; break; ... case state5: b >>= g16; m |= b; x = *(--geom); if (TEST) { state = ODD(x) ? state2 : state1; } else { g4 = (x+1)/2; state = ODD(x) ? state3 : state4; } break; } -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
franka@mmintl.UUCP (Frank Adams) (04/19/88)
In article <4160@auspyr.UUCP> mick@auspyr.UUCP (Michael J. Andrew) writes: >Provide each member of the team a $500 bonus at the start of a new >project, but deduct $50 each time a global variable is introduced >into the design. This isn't good enough. One can simply create a struct with one component for each thing which would otherwise be a global variable, and have a single instance of it as the only global variable. This makes the code harder to read, of course, but it saves (the team) money. -- Frank Adams ihnp4!philabs!pwa-b!mmintl!franka Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108
karl@haddock.ISC.COM (Karl Heuer) (04/19/88)
In article <1988Apr16.223658.15649@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >>[re languages so rich in control structures that goto is superfluous] >Don't forget the Unix shell. (The standard one, not the silly thing from >Berkeley.) It isn't sufficiently rich, at least not for my taste. Some things I've had to write in shell are worse than a goto. (Functions would help, but older shells don't have them yet, so I avoid them when I need portability.) Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
piet@ruuinf.UUCP (Piet van Oostrum) (04/19/88)
Posting-Front-End: GNU Emacs 18.47.9 of Mon Mar 21 1988 on ruuinf (hcx/ux) In article <1073@maynard.BSW.COM> campbell@maynard.BSW.COM (Larry Campbell) writes: In article <2618@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: <>...And I know of no language, with the possible exception of Ada, that is <>rich enough in control structures to always have an elegant and <>efficient alternative to using a goto. Check out BLISS. It's not without its flaws -- I consider its extreme typelessness a botch -- but it has such a complete set of well thought out control constructs that you don't miss the goto at all. (BLISS has no goto.) Modula-2 doesn't have a GOTO either. It has LOOP ... EXIT ... END. -- Piet van Oostrum, Dept of Computer Science, University of Utrecht Budapestlaan 6, P.O. Box 80.012, 3508 TA Utrecht, The Netherlands Telephone: +31-30-531806 UUCP: ...!mcvax!ruuinf!piet
les@chinet.UUCP (Leslie Mikesell) (04/20/88)
In article <1842@faline.bellcore.com> purtill@math.mit.edu (Mark Purtill) writes: >In any case, I fail to see how replacing a "return" with a "goto" will >make it any less confusing, especially given that the label for the goto >may be on the next page, or that the next person to deal with the code >may add code after the label, etc. All you've done is replace earlier >"return"s with "goto label"s which may not really do what you want. Do people still look at code on paper? A reasonable editor can find goto's and their targets no matter what page they are on. In all the ranting about writing code that is easy to maintain, no one has mentioned the things that allow the usual tools to do more of the work for us. For example, making all (at least global) names unique to the point that grep can find exactly the lines that use each one. Les Mikesell > >^.-.^ Mark Purtill >((")) purtill@math.mit.edu
terry@wsccs.UUCP (Every system needs one) (04/20/88)
In article <1988Apr11.201934.20594@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > Sorry, I consider the remark well-justified and will not apologize. If > you read my other postings on the subject, you will see that I consider > the use of gotos, especially the frequent use of gotos, to be a sign of > poor organization and "coding before thinking". Given this opinion, it > is hardly surprising that I would be reluctant to buy software from an > organization which endorses routine use of gotos. #ifdef FLAME You probably don't believe in "register" or "char ***", either. A language feature is there for a reason, or it rots and falls off, much like a human cerebellum. Coding before thinking is when all your local variables are named "foo" and all your global variables are named "fee", "fie", "foe", and "fum". Your functions are named "func1", "func2", etc., and your comments consist of "Begin program" and "End program". This is the result of not thinking. Use of conditional flags which may have to be loaded from memory is thinking twice and saying "think think ... click click". The use of the "goto" statement is much profaned by ex-Pascal programmers who have almost, but not quite, seen the light. These are the same people who do: #define BEGIN { #define END. } #define END } #define REMARK(x) /* (x) */ #define THEN #define IF if and IF (cond) THEN BEGIN ... ... END They are the same people who who use if (cond) { } and #define otherwise default switch (val) { case 1: ... ... case n: otherwise: } and int function() Instead of if( cond) { } and switch( val) { case 1: ... ... case n: default: } and int function() I like to call these people NOT-C programmers (say it out loud :-) They are the people who do not realize that grep goto /usr/src/uts/3b2/*/*.c | wc yeilds: 308 992 8411 ...308 "goto"'s in the UNIX kernel. (I checked... NONE were comments). I thinks this adequately justifies the use of "goto"'s in commercial programming, at least for those programs expected to PERFORM like a commercial program. Try the following some time. Replace all your "nifty" flags with "goto" statements, and profile both versions of the code... then, disassemble both versions and grep for all branch instructions. Which has more REAL "goto"'s? #else I'm not saying that "goto"'s should be used in place of all loop flags, but it certainly seems to make code a lot more readable if you don't have to use a 264 column terminal. If you use "goto"'s in place of flags which are modified in one place only for the express purpose of avoiding a "goto", you certainly clean up the assembly code, as well. #endif | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'There are monkey boys in the facility. Do not be alarmed; you are secure' |
sullivan@vsi.UUCP (Michael T Sullivan) (04/21/88)
In article <225800022@uxe.cso.uiuc.edu>, mcdonald@uxe.cso.uiuc.edu writes: > ... > tool is at hand to get the job done. I frankly don't believe for > ONE CLOCK TICK OF A CRAY 2 that gotos make code worse. Spaghetti is > ... > Professor of Chemistry ^^^^^^^^^ Hmmm... -- Michael Sullivan {uunet|attmail}!vsi!sullivan sullivan@vsi.com HE V MTL
new@udel.EDU (Darren New) (04/21/88)
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. >> ... > >Now give me something hard. > >Gary Samuelson How about: (pseudocode) for (i = 0; i < max_in_table && key != name[i]; ++i) if (keypressed()) goto handle_key; seek(helpfile, offset[i]); if (keypressed()) goto handle_key; linecount = 0; do { read_line_from_file(); ++linecount; if (keypressed()) goto handle_key; if (read_line[0] == special_flag_char) goto handle_key; insert_spaces_and_color_codes(); if (keypressed()) goto handle_key; display_text_line(); if (keypressed()) goto handle_key; } while (linecount < 24); handle_key: c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... } I contend that if the reading and formatting and displaying are sufficiently slow, such behaviour can be desirable (i.e., on microcomputers). I would like to see a goto-less version of this that is easier to understand. - Darren New Graduate Student University of Delaware.
hutch@hubcap.UUCP (David Hutchens) (04/21/88)
From article <2200@louie.udel.EDU>, by new@udel.EDU (Darren New): > > How about: (pseudocode) > for (i = 0; i < max_in_table && key != name[i]; ++i) > if (keypressed()) goto handle_key; > seek(helpfile, offset[i]); > if (keypressed()) goto handle_key; > linecount = 0; > do { > read_line_from_file(); > ++linecount; > if (keypressed()) goto handle_key; > if (read_line[0] == special_flag_char) goto handle_key; > insert_spaces_and_color_codes(); > if (keypressed()) goto handle_key; > display_text_line(); > if (keypressed()) goto handle_key; > } while (linecount < 24); > handle_key: > c = wait_for_key_then_read_it(); > switch (c) { > case 'A': ... > ... > } > > I contend that if the reading and formatting and displaying are sufficiently > slow, such behaviour can be desirable (i.e., on microcomputers). > I would like to see a goto-less version of this that is easier to understand. > - Darren New > Graduate Student > University of Delaware. > > for (i=0; i<max_in_table && key!=name[i] && !keypressed(); i++); if (!keypressed()) { seek(helpfile,offset[i]); looking_for_flag = 1; linecount = 0; while (looking_for_flag && linecount<24 && !keypressed()) { read_line_from_file(); linecount++; looking_for_flag = (read_line[0] != special_flag_char); if (looking_for_flag && !keypressed()) { insert_spaces_and_color_codes(); if (!keypressed()) { display_text_line(); } } } } c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... } Consider it done. The important thing to note is that I don't care if the precise algorithm you used can be done without a goto. In fact, it is the algorithm that is the problem. It is stupid to write a piece of code with gotos and then translate it to "structured" code. I put structured in quotes because such code is not structured at all. Indeed, in my implementation I may call keypressed a second time after I've already received a true response. This could be fixed easily enough with another local variable, but that would just make it harder to understand. I did use a looking_for_flag to maintain some information. I'm just waiting for the first fool to tell me it is not as efficient as your solution. ("I contend that if the reading and formatting and displaying are sufficiently slow," nobody could possibly notice these few microseconds.) The reason you don't see structured solutions is that you allow those silly gotos to control your reasoning. I insist on remaining in charge of my code. Actually, I'd write the first lines as: for (i=0; i<max_in_table && key!=name[i]; i++); if (!keypressed()) { .... since unless max_in_table is a bigger number than the available memory on most micros (your stated environment) I can check the whole array in less time than a few calls to keypressed() will take and certainly in less time than a user will be able to notice. I also note that there is no action taken in the case that i==max_in_table (other than seeking to God knows where). I suspect missing logic in your code. In summary, think about the problem and don't let gotos get in the way. David H. Hutchens Clemson University gatech!hubcap!hutch hutch@hubcap.clemson.edu
lew@gsg.UUCP (Paul Lew) (04/21/88)
> How about: (pseudocode) > for (i = 0; i < max_in_table && key != name[i]; ++i) > if (keypressed()) goto handle_key; > seek(helpfile, offset[i]); > if (keypressed()) goto handle_key; > linecount = 0; > do { > read_line_from_file(); > ++linecount; > if (keypressed()) goto handle_key; > if (read_line[0] == special_flag_char) goto handle_key; > insert_spaces_and_color_codes(); > if (keypressed()) goto handle_key; > display_text_line(); > if (keypressed()) goto handle_key; > } while (linecount < 24); > handle_key: > c = wait_for_key_then_read_it(); > switch (c) { > case 'A': ... > ... > } > > I contend that if the reading and formatting and displaying are sufficiently > slow, such behaviour can be desirable (i.e., on microcomputers). > I would like to see a goto-less version of this that is easier to understand. I think judicious use of goto is ok, but in this example, I think the following code is easier to understand than your code. The block stucture and ESPECIALLY indentation make it easier to understand, I have to read your version line by line to figure out what it does. int kp = 0; /* keypress indicator */ for (i = 0; i < max_in_table && key != name[i]; ++i) if (kp = keypressed()) break; if (!kp) { seek(helpfile, offset[i]); if (!keypressed()) { linecount = 0; do { read_line_from_file(); ++linecount; if (keypressed() || read_line[0] == special_flag_char) break; insert_spaces_and_color_codes(); if (keypressed()) break; display_text_line(); if (keypressed()) break; } while (linecount < 24); } } c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... -- Paul Lew {oliveb,harvard,decvax}!gsg!lew (UUCP) General Systems Group, 5 Manor Parkway, Salem, NH 03079 (603) 893-1000
ray@micomvax.UUCP (Ray Dunn) (04/22/88)
In article <451@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >.... >Mr Spencer, Mr. David Brown, and the loquacious Mr. Gwyn all say straight >out that I am an advocate of the use of the goto statement. >But I never once in any of my postings endorsed the use of the goto >statement! You may verify as much if you will reread the postings. Unfortunately, it is all too common on the net, even (especially?) by the supposed "gurus", that a reasoned *non-polarized* argument is immediately taken as a critisism. If you are not with them, you are judged to be against them! It happens to all of us. > ... I only stated that the importance which some people place >on avoiding the gotos is exceedingly exaggerated, and that time spent >campaigning against its use is misspent. This is an opinion which I >still hold. As do many of us! > >But all this is quite incidental. Mr. Spencer is entitled to his >opinions about programming techniques, as am I. >I objected not to Mr. Spencer's mistaken reading of my postings. >I objected to his affrontary. > Ok. You object. All this does now though, is open up another discussion as to what is "acceptable" behaviour on the net. You have expressed your opinion, they have too, by example. Both opinions should be respected, if not necessarily agreed with. >You three, Spencer, Brown, and Gwyn, hold that it is proper for you to >publicly criticize the software produced by the company which employs me, >on the basis of a few lines that I wrote here. To presume that >you are competent to judge products you have never used is >ridiculous. To presume to make such pronouncements publicly is, >by my values, rude at best. Perhaps I should only say that we have >differing values not only about some small software engineering matters, >but also about what constitutes good manners and acceptable behavior. > >I find this whole matter very distasteful. I regret having provoked it. > I'm not fully supportive of your *attitude* here, as the net is essentially a "soap-box" forum. A poster *must* realize that (s)he is exposing himself to all extremes of opinion, attitude, and behaviour, *and be prepared to take the heat*. A net poster is like an actor on a stage, (s)he must be prepared to accept criticism of all sorts. Support is, by its very nature, most often silent, except in private e-mail responses. Why can't you allow your opinions to stand on their own merits with the net readership as a whole? Just because Spencer, Gwyn, et al, disagree with your views does not denigrate your opinions in the eyes of the open-minded. Indeed, as I believe in this case, the *opposite* is often correct. They don't "hold that it is proper to", they just spout off, in what is, by now, an expected and predictable way. *They* are exposing themselves in the same way you are. I'm afraid I can't accept whining about "bad manners" in this sort of forum. To begin with, the right to be "bad mannered" is an intrinsic freedom just as important as the right to hold stupid opinions. Are you "hurt" by an opposing opinion? Should you be "hurt" by a badly mannered opposing opinion? I think not. Remember also, that the definitions of bad manners and stupid opinions are extremely subjective. Finally, what you are seeing on the net, is the *mental* responses which do not get moderated by speech or personal contact - we are all in our own little worlds here responding to faceless words! There is no definition of "bad manners" which has had time to mature in this environment. Many of us, including myself, expose ourself in both ways. So, people disagree some of the time, people are offended some of the time. Unfortunate, perhaps, but (profound statement follows (:-)) that's life! There's *always* going to be somebody that disagrees, and there's *always* going to be somebody whose reaction differs from your norms. >I'm through with comp.lang.c for a while. A pity, I respect your views, but it is probably for the best until you realize that a net posting is very different from expressing an opinion in private to a friend. Confidence in yourself and a thick skin are very useful attributes. Ray Dunn. ..{philabs, mnetor}!micomvax!ray
friedl@vsi.UUCP (Stephen J. Friedl) (04/22/88)
In article <2200@louie.udel.EDU>, new@udel.EDU (Darren New) writes: > > [responding to the "give me something hard to translate" challenge] > > How about: (pseudocode) > for (i = 0; i < max_in_table && key != name[i]; ++i) > if (keypressed()) goto handle_key; > seek(helpfile, offset[i]); > if (keypressed()) goto handle_key; > > [more code with output and "keypressed" here. Presumably > this lets redisplay stop and process the next command and > possibly avoiding wasted output. Emacs and WordStar do > this, among others] > > I contend that if the reading and formatting and displaying are sufficiently > slow, such behaviour can be desirable (i.e., on microcomputers). > I would like to see a goto-less version of this that is easier to understand. Let's put this goto business in perspective: /* * strcpy() - written by John Doe */ strcpy(dst, src) char dst[], src[]; { int i; for (i = 0; dst[i] = src[i]; i++) ; } Who objects to this? Even a beginnermediate C programmer is likely to rewrite this function using pointers, but it is unlikely that a passionate hatred of [arrays] (or of John Doe) will develop as well. In this case, the use of arrays indicates lack of experience or insight, not of evil intent or laziness. *********************************************** * The problem is not with arrays but with the * * underlying thought that caused their use. * * * * The solution is not to ban the array but to * * teach the insight. * *********************************************** And so it goes with our bedeviled goto. In the quoted text above, goto probably indicates a lack of experience with really neat methods of preemptive redisplay. Gosling Emacs does this by checking for keypressed() *one place* very deeply in the display handler rather than sprinkle these calls everywhere; Sys V Rel 3 curses does it like this too. I have oversimplified it here, but it is extremely elegant and beautiful to behold. Those attempting mere transliteration of the above fragment are condemned to failure even if no gotos are used -- the failure just won't be as "obvious". *********************************************** * The problem is not with the goto but with * * the underlying thought that caused its use. * * * * The solution is not to ban the goto but to * * teach the insight. * *********************************************** The array example is a trivial one but (I believe) valid. When you are learning C you will naturally stumble over the syntax and semantics of the language, but it is part of learning. In my opinion, *excessive* use of arrays tells me that the user needs to get more comfortable with pointers, but I betcha this person does not believe that they are doing anything "wrong". Perhaps they are not: the program works, doesn't it? Once you've learned C you still have a long way to go. There are many, many more levels of insight beyond just learning syntax -- learning to speak Spanish won't make you a great speaker in Mexico City. The goto shows lack of insight on a much higher level, and it is a lot harder to convince people that they are missing that insight. Showering users of gotos with $50 fines and ridicule is hardly conducive to inspired thinking. The solution to this goto problem is not to be found by banning the goto but by better fundamental understandings. Focusing on language syntax is largely a wasted effort that distracts from the real issues. C'mon guys/gals, let's replace: "you show me a fragment with gotos and I can rewrite it without them" (said with challenging tone) with "You show me what you want to accomplish, and I'll suggest some alternate ideas" (said with helpful tone). If you use gotos a lot, ask a wizard for suggestions and try to gain something beyond solving the problem at hand. If you are a wizard, share your experience as others undoubtedly did with you. Most of us really enjoy the fun of computers and want to be the best we can be. Let's help each other out. I've crossposted this to comp.software-eng in the hope that some of the net.readers over there might have something to offer from a software engineering viewpoint rather than a language syntax viewpoint. Anyone? -- Steve Friedl V-Systems, Inc. Resident access(2) basher friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl
campbell@maynard.BSW.COM (Larry Campbell) (04/22/88)
In article <2200@louie.udel.EDU> new@udel.EDU (Darren New) writes: <>How about: (pseudocode) <> for (i = 0; i < max_in_table && key != name[i]; ++i) <> if (keypressed()) goto handle_key; <> seek(helpfile, offset[i]); <> if (keypressed()) goto handle_key; <> linecount = 0; <> do { <> read_line_from_file(); <> ++linecount; <> if (keypressed()) goto handle_key; <> if (read_line[0] == special_flag_char) goto handle_key; <> insert_spaces_and_color_codes(); <> if (keypressed()) goto handle_key; <> display_text_line(); <> if (keypressed()) goto handle_key; <> } while (linecount < 24); <> handle_key: <> c = wait_for_key_then_read_it(); <> switch (c) { <> case 'A': ... <> ... <> } Use a signal handler. Example: handle_key() { c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... } } ... main body of code: signal(SIGIO, handler); for (i = 0; i < max_in_table && key != name[i]; ++i) ; seek(helpfile, offset[i]); linecount = 0; do { read_line_from_file(); ++linecount; insert_spaces_and_color_codes(); display_text_line(); } while (linecount < 24); This is not only much clearer and easier to read, it's also considerably faster. And doesn't use gotos. -- Larry Campbell The Boston Software Works, Inc. Internet: campbell@maynard.bsw.com 120 Fulton Street, Boston MA 02109 uucp: {husc6,mirror,think}!maynard!campbell +1 617 367 6846
chris@mimsy.UUCP (Chris Torek) (04/23/88)
>In article <2200@louie.udel.EDU> new@udel.EDU (Darren New) writes: [pseudocode with `goto handle_key'] In article <1075@maynard.BSW.COM> campbell@maynard.BSW.COM (Larry Campbell) suggests: >Use a signal handler. [code deleted] Remember also to fcntl(fd, FSETFL, FASYNC) or ioctl(fd, FIOASYNC, &on), or you will never get a signal. >This is not only much clearer and easier to read, it's also considerably >faster. And doesn't use gotos. It may be clearer and easier to read, but it is also more dangerous. Doing I/O in a signal handler is considerably harder than polling for input at `safe' places. If the input is to do almost anything useful, you have created a critical section, which requires blocking and releasing signals. The trivial if unclear `goto' variant has been replaced by a more powerful, more efficient (perhaps*), but much harder to code correctly, asynchronous variant. ----- *If the signal blocking and releasing has much overhead, it may be less efficient than the polling variant. Fortunately one can cheat and move the work into the io signal handler, using semaphore variables. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
nather@ut-sally.UUCP (Ed Nather) (04/23/88)
In article <993@micomvax.UUCP>, ray@micomvax.UUCP (Ray Dunn) writes: [... much very sensible discussion deleted ...] > a "soap-box" forum. A poster *must* realize that (s)he is exposing himself ^^^^^ ^^^^^^^ Twisting the language to become gender-free is not so easily done, as this example demonstrates. You have to change *all* references to a variable, not just some of them, if the code is to work. -- Ed Nather Astronomy Dept, U of Texas @ Austin {allegra,ihnp4}!{noao,ut-sally}!utastro!nather nather@astro.AS.UTEXAS.EDU
henry@utzoo.uucp (Henry Spencer) (04/24/88)
> You probably don't believe in "register" or "char ***", either. I use the former frequently and would use the latter if it seemed indicated, although I don't recall ever needing it. > A language feature is there for a reason... Language designers and standardizers do have to consider badly-written existing code as such a reason, remember. > ...308 "goto"'s in the UNIX kernel. (I checked... NONE were comments)... > I thinks this adequately justifies the use of "goto"'s in commercial > programming... Believe it or not, some of us do not consider the Unix kernel a shining example of wonderful programming (although it is mostly okay, and it does work pretty well). > Try the following some time. Replace all your "nifty" flags with "goto" > statements, and profile both versions of the code... If you read the paper by Geoff Collyer and myself in last year's winter Usenix proceedings, I think you will realize that I know how to profile things, and also how to make them run fast without assembler or gotos (C News contains neither). > then, disassemble > both versions and grep for all branch instructions. Which has more > REAL "goto"'s? Personally, I don't care diddly-squat about how ugly the code coming out of the compiler is. I don't usually read it. What I care about is the cleanliness of the source code, which I do have to read, and the speed and correctness of the object code. Turning clean human-readable notation into ugly fast code is the compiler's *JOB*. > ... If you use "goto"'s in place of flags > which are modified in one place only for the express purpose of avoiding a > "goto", you certainly clean up the assembly code, as well. If you use neither, the source code generally looks still better, and the assembler might well improve too (if you care). I'm not sure I've ever used a flag just to avoid a goto; certainly I haven't done it recently. I believe in treating the disease, not the symptoms. > The use of the "goto" statement is much profaned by ex-Pascal programmers > who have almost, but not quite, seen the light... Well, speaking for myself, I've never programmed in Pascal. I suppose I may not have seen the light yet; I've only programmed in C for 13 years. -- "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology non-negotiable." --DMR | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
g-rh@cca.CCA.COM (Richard Harter) (04/24/88)
I suppose there is some justification for the recurring issue of gotos -- it usually raises some interesting issues of coding technique. It's not a profound topic, but it's fun for all concerned. It seems to me that the profit, if any, in these exercises is to analyze these little difficulties and spot where the problem is and what a good resolution is. In the case in hand we have a very common task -- there are a series of actions. After each action we check to see if a certain thing has happened -- if it has we cease stepping through the actions and go on to the next stage. The proposed techniques include a) Use goto's at each checkpoint which branch to a common label b) Fake it with a block and break statements c) Use nested if's d) Use a signal handler. The signal handler approach is pretty, but it isn't general, and doesn't really work right in this case. The nested if's approach is, in my view, worse than using goto's -- it buries the essential structure of the task rather than explicates it. Block and break is fine as long as it is con- venient to put all the tests at the first level. So far, however, nobody has really made a good case for not using goto's for this kind of task, as far as I can see, other than it is naughty to use goto's. Here are some more alternatives: e) Put the sequence of actions in a function and get out with return statements. Much the same as block and break, except that you can do deep level escapes. f) Put the test condition in a while statement and step through the actions [somehow]. Unfortunately, I don't see a nice way to do this in C. The thought that first occurs to one is something like for (step=0,done=0;!done;step++) { switch(step) { case 0: action_0; break; case 1: action_1; break; ...... default: done = 1; break; } if (!done && test_condition) done=1; } which is all very well in its way (there is now only one expression of the test condition) but does look remarkably clumsy and is a maintenance problem (what happens when you want to insert a new action?). Perhaps someone else has a neater way to do it. In assembly language this type of situation is a natural for threaded code. The labels for the action sequences go on a stack. After each action you branch to the test code, which in turn pops the next action label. All very straightforward, but I don't really see a nice way to implement threaded code in C without using function arrays. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.
flaps@dgp.toronto.edu (Alan J Rosenthal) (04/24/88)
In article <1464@hubcap.UUCP> hutch@hubcap.UUCP (David Hutchens) writes: >Indeed, in my implementation I may call keypressed a second >time after I've already received a true response. This could be >fixed easily enough with another local variable, but that would just >make it harder to understand. Better yet, if keypressed() is considered part of the i/o library, it could keep its own local flag, if the following two changes were made: -> When keypressed() is called, if the flag is set, just return true; else actually look for a keypress and if there is one then set the flag and return true. -> All other input functions clear the flag if they do actual input. As an optimization, perhaps ungetc() sets the flag (scanf() too if applicable). In fact, keypressed() probably already works like this. If not, you can certainly wrap your own routine around it, or write your mykeypressed() routine that keeps a flag and does the low-level gunge itself. ajr
peter@sugar.UUCP (Peter da Silva) (04/24/88)
I think you're both hosed... In article ... campbell@maynard.BSW.COM (Larry Campbell) writes: > In article <2200@louie.udel.EDU> new@udel.EDU (Darren New) writes: > <>How about: (pseudocode) > <> for (i = 0; i < max_in_table && key != name[i]; ++i) > <> if (keypressed()) goto handle_key; ... > <> handle_key: > <> c = wait_for_key_then_read_it(); > <> switch (c) { > Use a signal handler. Example: > handle_key() > { > c = wait_for_key_then_read_it(); > switch (c) > { ... > ... main body of code: > signal(SIGIO, handler); > for (i = 0; i < max_in_table && key != name[i]; ++i) > ; Who's got SIGIO? And why do you need SIGIO? Instead of if(key_pressed()) goto handle_key; You can do if(key_pressed()) handle_key(); Personally I'd do this in a real operating system that supports lightweight processes, like AmigaDOS, instead of an old monolithic monitor :->. -- -- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter -- "Have you hugged your U wolf today?" ...!bellcore!tness1!sugar!peter -- Disclaimer: These aren't mere opinions, these are *values*.
daveb@geac.UUCP (David Collier-Brown) (04/25/88)
>In article <451@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes: >>Mr Spencer, Mr. David Brown, and the loquacious Mr. Gwyn all say straight >>out that I am an advocate of the use of the goto statement. >>But I never once in any of my postings endorsed the use of the goto >>statement! You may verify as much if you will reread the postings. Point of fact: My name is Collier-Brown (just ask Joyce!). Point of fact: I'm the guy who said Dave Jones condoned gotos, and said Henry Spencer could fine me when I used them. Point of order: Its OK to get mad at me, I have a relatively thick skin. (I have to, I still use gotos for things (:-)). --dave (My first language was FORTRAN II) c-b -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers International Inc., | Computer Science loses its 350 Steelcase Road,Markham, Ontario, | memory (if not its mind) CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.
dg@lakart.UUCP (David Goodenough) (04/25/88)
In article <2200@louie.udel.EDU> new@udel.EDU (Darren New) writes: >How about: (pseudocode) > for (i = 0; i < max_in_table && key != name[i]; ++i) > if (keypressed()) goto handle_key; > seek(helpfile, offset[i]); > if (keypressed()) goto handle_key; > linecount = 0; > do { > read_line_from_file(); > ++linecount; > if (keypressed()) goto handle_key; > if (read_line[0] == special_flag_char) goto handle_key; > insert_spaces_and_color_codes(); > if (keypressed()) goto handle_key; > display_text_line(); > if (keypressed()) goto handle_key; > } while (linecount < 24); > handle_key: > c = wait_for_key_then_read_it(); > switch (c) { > case 'A': ... > ... > } This is about the same: for (i = j = 0; i < max_in_table && key != name[i] && !j; ++i) if (j = keypressed()) break; if (!j) { seek(helpfile, offset[i]); linecount = 0; while (!keypressed() && linecount < 24) { read_line_from_file(); ++linecount; if (keypressed() || read_line[0] == special_flag_char) break; insert_spaces_and_color_codes(); if (keypressed()) break; display_text_line(); } } c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... } I grant that j could be renamed to (say) key_press_seen, but choice of long / short variable names belongs in a whole different discussion. However, I ask, where did all those goto's go to?? :-) The ONLY time I use a goto is because C doesn't have a 'break 2' construct: for (;;) { while (...) { code ..... if (condition) break 2; more code ..... } } /* break 2 exits to here */ Maybe someone should suggest it to the ANSI crowd - it can't be that hard to do. -- dg@lakart.UUCP - David Goodenough +---+ | +-+-+ ....... !harvard!adelie!cfisun!lakart!dg +-+-+ | +---+
garys@bunker.UUCP (Gary M. Samuelson) (04/26/88)
In article <2200@louie.udel.EDU> new@udel.EDU (Darren New) writes: >How about: (pseudocode) For pseudocode it looks a lot like C. The easy way: replace "goto handle_key" with "return." Then after the call to this function, add a call to handle_key(). You have too much going on for it to be one function anyway. What you really want is to get an interrupt if a key is pressed. If you can do that, then the code becomes much simpler. If you can't get either a "key pressed" interrupt or an interval timer interrupt, then use a state machine. (Credit has to go to Dave Burton; although I frequently use state machines, I hadn't thought of it in the previous case.) while( state != done ) { /* Instead of 'state', 'next_thing_to_do' might be better */ switch( state ) { case readingfile: ... if( read_line[0] == special_flag_char ) state = done; else state = inserting_spaces_and_color_codes; break; case inserting_spaces_and_color_codes: ... state = displaying_text_line; break; ... case last_thing_to_do: state = done; break; } /* end of switch (state) */ if( keypressed() ) state = done; } /* end of while( state != done ) */ c = wait_for_key_then_read_it(); switch (c) { case 'A': ... ... } It still reads sequentially, but now "if keypressed" is isolated, which makes it less cluttered, and easier to change if (no, when) it becomes necessary to do any of the following: 1. pass an argument to keypressed(); 2. check something else periodically; 3. add or delete points at which the check is made; >I would like to see a goto-less version of this that is easier to understand. I hope you think I have done so. Gary Samuelson
mls@whutt.UUCP (SIEMON) (04/26/88)
In article <11352@ut-sally.UUCP+, nather@ut-sally.UUCP (Ed Nather) writes: + In article <993@micomvax.UUCP>, ray@micomvax.UUCP (Ray Dunn) writes: + + [... much very sensible discussion deleted ...] + + > a "soap-box" forum. A poster *must* realize that (s)he is exposing himself + ^^^^^ ^^^^^^^ + Twisting the language to become gender-free is not so easily done, as this + example demonstrates. You have to change *all* references to a variable, + not just some of them, if the code is to work. Yes; as a good rule of thumb, it is MUCH easier to recast your sentences into plural forms (where English makes no gender distinctions) than to go into contortions to "fix" a sentence you have already warped by using the singular. The pluralizing tactic will almost always work (outside of specific references to individuals, where acknowledging gender is usually innocuous.) This is a nice analogue of the problems with "go to" in programming languages; the occurence of the deprecated form is a good sign (with some rare exceptions, as has been mentioned in this discussion) that you have probably not thought out the problem first. -- Michael L. Siemon contracted to AT&T Bell Laboratories ihnp4!mhuxu!mls standard disclaimer
terry@wsccs.UUCP (Every system needs one) (04/28/88)
In article <1988Apr24.012322.3951@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > > A language feature is there for a reason... > > Language designers and standardizers do have to consider badly-written > existing code as such a reason, remember. Standardizers, yes; designers, no. If you degisign a language, then there is not existing code. ANSI isn't considering "badly written" code, aparrently, although defining "badly written" in a standard that makes something badly written is begging the question. > > > ...308 "goto"'s in the UNIX kernel. (I checked... NONE were comments)... > > I thinks this adequately justifies the use of "goto"'s in commercial > > programming... > > Believe it or not, some of us do not consider the Unix kernel a shining > example of wonderful programming (although it is mostly okay, and it does > work pretty well). It would be slower in a number of cases without the construction it has... consider the generation of "init", fo instance. I wasn't saying it was wonderful; simply adequate, and in some cases more efficient due to it's use of goto's... > > Try the following some time. Replace all your "nifty" flags with "goto" > > statements, and profile both versions of the code... > > If you read the paper by Geoff Collyer and myself in last year's winter > Usenix proceedings, I think you will realize that I know how to profile > things, and also how to make them run fast without assembler or gotos > (C News contains neither). There are some cases where goto's *SHOULD* be used for efficiency where the compiler or optimizer doesn't have a snowball's chance in hell of figuring out what I wrote for itself. Better to hit it over the head with what you consider a hammer than to be less efficient. > > then, disassemble > > both versions and grep for all branch instructions. Which has more > > REAL "goto"'s? > > Personally, I don't care diddly-squat about how ugly the code coming out > of the compiler is. I don't usually read it. What I care about is the > cleanliness of the source code, which I do have to read, and the speed and > correctness of the object code. Turning clean human-readable notation into > ugly fast code is the compiler's *JOB*. You don't agree that less of the same instructions == faster code? Goto's are not the unclean, wearing the red mask of death and knocking at your door. Are you trying to tell us that you have *NEVER* used a goto? How does a goto differ from a break statement when used to exit a for statement to the statement immediately after it... pages of code later? Why can't goto's be used, in your book, to handle non-standard conditions? > > > ... If you use "goto"'s in place of flags > > which are modified in one place only for the express purpose of avoiding a > > "goto", you certainly clean up the assembly code, as well. > > If you use neither, the source code generally looks still better, and the > assembler might well improve too (if you care). I agree with this, it's just that sometimes fugly code must be written to do something fast and elegantly. I simply think that a goto is less fugly than an equivalent failure-loop construct, and beats indenting (or worse, NOT indenting) everything. I happen to write code that uses for( ;;) { } instead of while( 1) { } too, as I need the best speed out of the hardware I can get and the 'for' avoids a test instruction being generated. Certainly, the 'while' is better at self-documenting, but it isn't the right tool for the job. > I'm not sure I've ever used a flag just to avoid a goto; certainly I haven't > done it recently. [...] > I've only programmed in C for 13 years. What do you write? > "Noalias must go. This is | Henry Spencer @ U of Toronto Zoology > non-negotiable." --DMR | {ihnp4,decvax,uunet!mnetor}!utzoo!henry For someone as vehnemently against 'noalias' as your .sig implies, how can you berate a current language feature? And how can you respect DMR's concept of C enough to quote him on it, but not respect his decision to include the 'goto' statement? Your appeal to his authority is a little inconsistent. | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'Admit it! You're just harrasing me because of the quote in my signature!' |
cl@datlog.co.uk (Charles Lambert) (04/28/88)
In article <27310@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes: > >f) Put the test condition in a while statement and step through the > actions [somehow]. Unfortunately, I don't see a nice way to do > this in C. The thought that first occurs to one is something like > >for (step=0,done=0;!done;step++) { > switch(step) { > case 0: action_0; > break; > case 1: action_1; > break; > ...... > default: done = 1; > break; > } > if (!done && test_condition) done=1; > } This is almost a finite-state machine, and state machine programming is an accepted idiom. Generalise it as follows: state=STAT0; while ( state != STATE_DONE ) { switch (state) { STATE0: action_0(); if (exit_condition_0) state = STATE_DONE; else state=STATE1; break; STATE1: action_1(); if (exit_condition_1) state = STATE_DONE; else state = STATE2; break; . . . } } Note that with this model, states may occur in any order and even repetitively. The "if...goto" construct is simply a sequential case of the general state machine. ----------------- Charles Lambert
terry@wsccs.UUCP (Every system needs one) (04/30/88)
In article <3490@bunker.UUCP>, garys@bunker.UUCP (Gary M. Samuelson) writes: [...] > What you really want is to get an interrupt if a key is pressed. > If you can do that, then the code becomes much simpler. If you > can't get either a "key pressed" interrupt or an interval timer > interrupt, then use a state machine. (Credit has to go to Dave > Burton; although I frequently use state machines, I hadn't thought of it > in the previous case.) how's about: extern volatile key_interrupt; for( ;;) { switch( whatever) { case 1: ... case 2: ... default: ... } if( key_interrupt) break; } | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'Admit it! You're just harrasing me because of the quote in my signature!' |
chris@mimsy.UUCP (Chris Torek) (04/30/88)
>>Personally, I don't care diddly-squat about how ugly the code coming out >>of the compiler is. I don't usually read it. What I care about is the >>cleanliness of the source code, which I do have to read, and the speed and >>correctness of the object code. Turning clean human-readable notation into >>ugly fast code is the compiler's *JOB*. [Henry Spencer] In article <504@wsccs.UUCP> terry@wsccs.UUCP (Every system needs one) writes: >You don't agree that less of the same instructions == faster code? I imagine he does. What do goto statements have with fewer instructions in the machine code? Answer: very little. Indeed, in a straightforward compiler `goto's produce branch instructions, which must be executed in addition to the inline instructions at the label to which the branch branches. So using `goto's often means executing *more* instructions, not fewer. Also note that in some architectures, branches are quite a bit slower than `regular' instructions; that one extra branch to merge with common code may take as much time as ten or fifteen of the instructions at the common code point. >How does a goto differ from a break statement when used to exit a for >statement to the statement immediately after it... pages of code later? `goto' statements have the `come-from' problem. (Fortunately, and especially with well-chosen labels, this problem is small enough in C, given a decent editor.) As an example, recently I was fixing various bugs in the 4BSD Vax peephole optimiser (see comp.bugs.4bsd). This thing is full of `goto's; in several instances I had to verify that the only way to reach some particular label was from one nearby `goto'. It is by no means obvious, given the ~400 line---and ugly multi-statement lines at that---`bmove' routine. Personally, I have little trouble with an occasional `goto', but I have noticed that use of `goto's tends to coincide with other practises that, all together, reduce readability and maintainability. As an aside, Terry mentions that [edited somewhat] >I happen to write code that uses > for( ;;) { >instead of > while( 1) { >as I need the best speed out of the hardware I can get and the 'for' >avoids a test instruction being generated. Any compiler that generates a `test 1' instruction for the while(1) loop should not be discarded lightly. It should be thrown away with great force. Great grief!, even PCC does not test constants! >Certainly, the 'while' is better at self-documenting, Is it? I happen to prefer `for (;;)'---to me this is an idiomatic expression for `forever'. (Using #define EVER ;; for (EVER) however, is tacky :-) .) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
henry@utzoo.uucp (Henry Spencer) (05/01/88)
> > Language designers and standardizers do have to consider badly-written > > existing code... > > Standardizers, yes; designers, no. If you degisign a language, then there is > not existing code. Only if you are designing a totally new language, as opposed to one like C++ that is upward-compatible with an existing language to some degree. In real situations as opposed to classroom exercises, upward-compatible extensions are rather more common than from-scratch designs. > ANSI isn't considering "badly written" code, aparrently... Not true, actually. X3J11 does not feel *compelled* to consider badly- written existing code. Sometimes it does, though; there are concessions to such pragmatic issues here and there, where it doesn't do too much violence to other objectives. > although defining "badly written" in a standard that makes something badly > written is begging the question. Only if you believe that no previous standard existed, which is wrong. There was no *formal* prior standard, and this caused a lot of fuzziness, but there was consensus on most things. (Otherwise formal consensus standardization like X3J11 would be impossible, after all.) In the absence of a carefully- written formal standard, there is more room for debate about whether specific code is badly written, but the term remains meaningful. > > ... Turning clean human-readable notation into > > ugly fast code is the compiler's *JOB*. > > You don't agree that less of the same instructions == faster code? IF other things are equal (they usually aren't), and IF the generated code is in fact different (it often isn't), then it is faster code. So what? Remember, I do not advocate bashing code after the fact to remove gotos; my experience is that well-organized code never needs them in the first place, so efficiency comparisons between goto code and bashed versions of it are irrelevant. > ... Are you trying to tell us that you have *NEVER* used a goto? Disregarding maintenance of goto-containing existing code, which sometimes is done under time-and-effort constraints that make major cleanup impossible, I haven't used one in quite a few years. I wouldn't say "never", but I don't recall the last occasion. > How does a goto differ from a break statement when used to exit a for > statement to the statement immediately after it... pages of code later? ... If you write such things, I suppose the answer is "not much". Personally, I consider *any* form of exit (except a function return) that goes to a point pages later to be a serious botch. > Why can't goto's be used, in your book, to handle non-standard conditions? Because there are better ways. > > I'm not sure I've ever used a flag just to avoid a goto; certainly I haven't > > done it recently. ... > > I've only programmed in C for 13 years. > > What do you write? Everything from small patches for existing code to quite large programs. The one major gap in my experience is not much involvement in huge multi- programmer multi-year projects... which in my opinion are doomed anyway unless they can be split into manageable pieces. > For someone as vehnemently against 'noalias' as your .sig implies, how can > you berate a current language feature? ... Criticism of new mistakes does not require embracing old ones. Do remember, also, that I berate human use of the feature, not its existence -- I have no quarrel with its use in mechanically-generated code, for example. > And how can you respect DMR's concept > of C enough to quote him on it, but not respect his decision to include the > 'goto' statement? Your appeal to his authority is a little inconsistent. Even if one ignores some of the considerations mentioned above, it is quite possible to respect Dennis's overall concept of the language and his views on certain specific issues while disagreeing with him on others. -- NASA is to spaceflight as | Henry Spencer @ U of Toronto Zoology the Post Office is to mail. | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
levy@ttrdc.UUCP (Daniel R. Levy) (05/02/88)
Henry, If you really, truly believe that "properly designed" code practically never needs a goto, you ought to write a book on the subject. I mean this in all seriousness. Just lording it over the "unenlightened" masses (actually, people who program AT ALL aren't a dumb bunch) without sharing the full secrets of your wisdom is tantamount to being smart alecky. -- |------------Dan Levy------------| Path: ihnp4,<most AT&T machines>!ttrdc!levy | AT&T | Weinberg's Principle: An expert is a | Data Systems Group | person who avoids the small errors while |--------Skokie, Illinois--------| sweeping on to the grand fallacy.
bts@sas.UUCP (Brian T. Schellenberger) (05/03/88)
In article <64@lakart.UUCP> dg@lakart.UUCP (David Goodenough) writes: | |The ONLY time I use a goto is because C doesn't have a 'break 2' construct: |Maybe someone should suggest it to the ANSI crowd - it can't be that hard to do. I submit that goto's are clearer than "break 2", and that the sentiment to add "break n" in order to purge gotos is a sign of people who have gotten so wrapped up a particular manifestation (gotos) of a problem (obscure code) that they are moved to ask for treatment for the symptoms even when they make the disease worse. This reminds me of the military, which is always fighting the previous war. (I would, however, support "break loop" for the special case of breaking out of a while/do/for loop from inside of a nested "switch". I find the inability to get out of there cleanly very annoying.) -- --Brian. (Brian T. Schellenberger) ...!mcnc!rti!sas!bts . . . now at 2400 baud, so maybe I'll stop bothering to flame long includes.
peter@athena.mit.edu (Peter J Desnoyers) (05/04/88)
In article <490@sas.UUCP> bts@sas.UUCP (Brian T. Schellenberger) writes: >(I would, however, support "break loop" for the special case of breaking out >of a while/do/for loop from inside of a nested "switch". I find the inability >to get out of there cleanly very annoying.) >-- > --Brian. >(Brian T. Schellenberger) ...!mcnc!rti!sas!bts I would consider the semantics of the switch statement to be the worst botch in the C language, obviously induced by reading lots of assembler code. Not to say that it's horrible, or anything, but 95% of the time I use a switch statement I don't use cases that fall through; whereas I find myself wishing I could use a switch to figure out how to break out of a loop a lot more than 5% of the time. (So far I've used gotos for this.) I would rather that the switch construct was used in the following way: switch (n) { case foo: statement_or_block case bar: } rather than overloading 'break' with two different meanings - one for switches, and another for do, while, and for loops. I would accept the use of 'continue' to fall through, even though the net aesthetic improvement would be zero. Of course, we can't change it now, and it's not too broken to use by any means... Peter Desnoyers peter@athena.mit.edu
daveb@laidbak.UUCP (Dave Burton) (05/04/88)
In article <2639@ttrdc.UUCP> levy@ttrdc.UUCP (Daniel R. Levy) writes: |Henry, |If you really, truly believe that "properly designed" code practically never |needs a goto, you ought to write a book on the subject. I mean this in all |seriousness. Just lording it over the "unenlightened" masses (actually, |people who program AT ALL aren't a dumb bunch) without sharing the full secrets |of your wisdom is tantamount to being smart alecky. Such a book already exists: _Software Tools_ by Kernighan & Plauger (and its sister, _Software Tools in Pascal_). This book provide an excellent example of 'good code', without using (any?) gotos. By extending FORTRAN to include control flow constructs besides the goto, K&P were able to write some moderately sophisticated programs (a roff-like text formatter, a text editor, and a ratfor preprocessor) without gotos. I would bet that most of you have at least heard of these books, which makes me wonder why nobody seems to acknowledge their existence, especially in light of all the recent 'what constitutes a good program' discussion. I have found them invaluable.
terry@wsccs.UUCP (Every system needs one) (05/14/88)
In article <1988Apr30.230243.15728@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: > > > Language designers and standardizers do have to consider badly-written > > > existing code... > > > > Standardizers, yes; designers, no. If you design a language, then there > > is not existing code. > > Only if you are designing a totally new language, as opposed to one like C++ > that is upward-compatible with an existing language to some degree. In real > situations as opposed to classroom exercises, upward-compatible extensions > are rather more common than from-scratch designs. This has no application to the subject of ANSI C introducing incompatibilities, unless you are implying that ANSI C is an upward compatible language rather than the standardization of an existing one. > > ANSI isn't considering "badly written" code, aparrently... > > Not true, actually. X3J11 does not feel *compelled* to consider badly- > written existing code. Sometimes it does, though; there are concessions > to such pragmatic issues here and there, where it doesn't do too much > violence to other objectives. Hmmm... this seems to lend even more creedence to the idea that what ANSI is doing is designing, not standardizing, when added to your prior statement. > > although defining "badly written" in a standard that makes something badly > > written is begging the question. > > Only if you believe that no previous standard existed, which is wrong. There > was no *formal* prior standard, and this caused a lot of fuzziness, but there > was consensus on most things. (Otherwise formal consensus standardization > like X3J11 would be impossible, after all.) In the absence of a carefully- > written formal standard, there is more room for debate about whether specific > code is badly written, but the term remains meaningful. Yes, but if the the code was not defined as "badly written" before the informal standard is "formalized" and is defined as "badly written" afterward, then the formalization has changed the definition and can not truly be considered to be "standardization". It reminds me of that Bill Cosby routine where Noah tells God "You change one of them". > > > ... Turning clean human-readable notation into > > > ugly fast code is the compiler's *JOB*. > > > > You don't agree that less of the same instructions == faster code? > > IF other things are equal (they usually aren't), and IF the generated code > is in fact different (it often isn't), then it is faster code. So what? Well, that "so what?" kind of put a damper on any of the reasonable arguments I could have used to refute the implication that slow code is a bad idea when compared to a trivial difference in coding style. > Remember, I do not advocate bashing code after the fact to remove gotos; > my experience is that well-organized code never needs them in the first > place, so efficiency comparisons between goto code and bashed versions of > it are irrelevant. Never, huh? Are you saying that everybody who has ever used a goto in the first place is, in fact, writing badly organized code? This is ridiculous. Am I expected to apply this to all languages? What do I use instead of a branch instruction in assembly? Repeated instructions? > > ... Are you trying to tell us that you have *NEVER* used a goto? > > Disregarding maintenance of goto-containing existing code, which sometimes > is done under time-and-effort constraints that make major cleanup impossible, > I haven't used one in quite a few years. I wouldn't say "never", but I > don't recall the last occasion. > > > How does a goto differ from a break statement when used to exit a for > > statement to the statement immediately after it... pages of code later? ... > > If you write such things, I suppose the answer is "not much". Personally, > I consider *any* form of exit (except a function return) that goes to a > point pages later to be a serious botch. For complicated algorythms which defy simplification, this makes for a great deal of pushing and popping, as well as greatly complicating the use of for statements, which must have an additional test to check to see if the flag is set. > > Why can't goto's be used, in your book, to handle non-standard conditions? > > Because there are better ways. Such as? Consider that you have a bunch of non-global fd's which have to be closed prior to exiting. In addition, each is required to have a byte sequence that indicates "END-OF-DATA" for another program. How is writing this with a procedure that requires 1) making the fd's global or 2) passing all of them, as well as generating 6 or so function references for the 6 or so locations where program flow determines an exit should occurr intrinsically better than simple goto statements to one location? > > > I've only programmed in C for 13 years. > > > > What do you write? > > Everything from small patches for existing code to quite large programs. > The one major gap in my experience is not much involvement in huge multi- > programmer multi-year projects... which in my opinion are doomed anyway > unless they can be split into manageable pieces. How large is quite large? How do you provide 1) utility 2) readability 3) speed 4) more speed > Criticism of new mistakes does not require embracing old ones. Do remember, > also, that I berate human use of the feature, not its existence -- I have no > quarrel with its use in mechanically-generated code, for example. A mechanical code generator that can't generate code which fits into a person's arbitrary standard of "goodness" is not a good thing, and therefore should not be used. Philosophically, this is why I believe there will always be programmers. Machines are too dumb to program well, and humans are (mostly) too smart to program mechanically... among other reasons for this being true is the simple, Darwinistic phrase "you're fired". Bad programmers "go away". | Terry Lambert UUCP: ...{ decvax, ihnp4 } ...utah-cs!century!terry | | @ Century Software OR: ...utah-cs!uplherc!sp7040!obie!wsccs!terry | | SLC, Utah | | These opinions are not my companies, but if you find them | | useful, send a $20.00 donation to Brisbane Australia... | | 'Admit it! You're just harrasing me because of the quote in my signature!' |
bill@proxftl.UUCP (T. William Wells) (05/20/88)
Under ordinary circumstances, there is exactly one place where a human C coder might use a goto. This is to implement multi-level breaks and continues. I say this, having managed (and written huge chunks of) a 17,000 line software system (and that is only the part we sell, and does not include development tools). I have programmed in C for six years now and have NEVER used a goto. We have uncounted megabytes of C code written in-house. None of it (to my knowledge) contains a goto. The closest thing we have to a goto is setjmp/longjmp, used to implement a multi-level return (and that is a recent change, one whose contemplation caused much debate). With that aside, let me explain why the goto discussion is really fruitless. People have observed that gotos are used in a lot of bad code. From this it is concluded that gotos are bad. This is really bad logic. Try this: programmers have been observed to write bad code; therefore, programmers are bad! THERE IS NOTHING WRONG WITH GOTO. (And how do I reconcile with my mouthing off above? Wait and see...) The thing that is screwed up is the control structures being implemented with the gotos. The whole point of the structured programming debate is this: every program has a control structure; some of these control structures are better than others. Whether you use gotos or some other language feature to implement the control structure does not change what the control structure is nor does it affect the goodness of the control structure. The quality of your program is strongly influenced by the quality of its control structures. Furthermore, you want that control structure to be obvious and understandable to the reader of the program. This implies that you use language features that make your use of a control structure obvious. So, the first question should be: what are the good control structures? The second question should be: given a particular language, how should the control structures be implemented? Ok, so what makes a control structure good? Well, the basic answers are: a control structure is good if it is 1) appropriate to solving programming problems. 2) easy to write. 3) easy to understand. 4) easy to maintain. 5) ... add your own as long as they do not contradict the above There are obviously lots of control structures that meet these requirements and you do not have to use all of them. In fact, you should pick a set of those which are most appropriate for your programming environment and use them. This set should be, in some sense, a minimum one; for example, if you have two control structures which can accomplish the same thing, but one is easier to use than the other (for you), pick the easier one and forget the other. All other things being equal, a smaller number of control structures helps make your program easier to understand. Now, I hope my claim about our C programs is understandable. But if not, here is what it amounts to: I have chosen a set of control structures which is appropriate to programming in C, for the kind of programming tasks that I do. It happens that, while my set of control structures includes multi-level breaks and continues (which would be implemented with a goto), I have never had need of one. Given the amount of code I write, it seems to me that one might never need to use an explicit goto in C code. Now that I think of it, here is a reason to avoid naked gotos in C code: for all other constructs, the control structure being implemented is obvious from the keywords employed. This is not true for goto. Therefore, supposing that you have found a control structure that you have to implement using gotos in C, you should dress the goto up. As an example, suppose that you are using the state machine control structure. I normally code it as: state = STATE_INIT; while (state != STATE_DONE) { switch (state) { case STATE_INIT: ... } } However, this is not the most efficient way to do it. You could also implement it as: /* Wherever you see the macros state and nextstate being used, you will be seeing a state machine. The state macro defines the start of a state. The nextstate macro causes a transfer of control to another state of the same machine. A state machine starts at a #define of statepref and ends with state(DONE). */ #define dummy(x) x #define state(x) dummy(statepref)x #define nextstate(x) goto dummy(statepref)x #ifdef statepref #undef statepref #endif #define statepref STATE_ state(INIT): ... code for this state nextstate(DONE); ... more states with the appropriate code state(DONE): ... code after the state machine (N.B. I am aware that not all preprocessors will do what I want here; for real portability, you would explicitly write the prefixes. Also, this method fails for nested state machines, something I have occasionally had need of.) Some of you will no doubt be thinking: but why should I go to all this effort when I could just use the goto directly? Well, if this was all you did with goto, I don't really see any reason why not (but I do think your program should include a comment saying that you use goto for state machines and describes how you structure it). If, however, you have more than one way of using goto, you should clothe the gotos somehow so that the reader of the program knows what control structure your goto belongs to. (After all, a while is just a disguised goto :-)