Xref: utzoo misc.misc:6030 comp.misc:6006 Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!unmvax!pprg.unm.edu!hc!lanl!jlg From: jlg@lanl.gov (Jim Giles) Newsgroups: misc.misc,comp.misc Subject: Re: The "evil" GOTO (Was: 25 Years of BASIC) Message-ID: <13301@lanl.gov> Date: 8 May 89 23:31:00 GMT References: <905@twwells.uucp> Organization: Los Alamos National Laboratory Lines: 82 From article <905@twwells.uucp>, by bill@twwells.uucp (T. William Wells): > In article <13113@lanl.gov> jlg@lanl.gov (Jim Giles) writes: > : if (cond1) { > : [...A...] /* lots of code */ > : goto LABEL;} > : else if (cond2) { > : LABEL: [...B...] /* lots more code */ > : } > [...] > : Solution 2) imposes a code space penalty > : as well as making code maintenance difficult (you must always remember to > : update _both_ versions of 'B'). > > Only half true. Many (most?) optimizers will recognize that the two > code sequences are identical and put the branch where you would > expect. There's a limit to what an optimizer can do. Suppose the example were a long sequence of "else if"s and that SEVERAL distinct branches all ended with sequence B. Or, suppose the long sequence of "else if"s contain some branches that end with sequence B and others that end with C where B and C are disjoint. Duplicating the code can waste a _lot_ of space and really make maintenance a nightmare! > [...] > Be aware that a *single* goto in a function can cause many optimizers > to do nothing for the function. The reason for this is that many of > the better optimization techniques depend on the program having a > particular control structure and transforming an arbitrary program > into one that is acceptable is a hairy task. This is _REALLY_ irritating though. The example above obeys all the "rules" of a well structured control construct: it has only one entry; it has only one exit; it flows strictly from top to bottom of the page; etc.. There _IS_ a language feature that allows this to be done with an accepted "structured" mechanism. I hesitate to mention it though, since it is _much_ less readible than the version with GOTOs - it was an "event driven" mechanism devised by Zahn (C.T. Zahn. "A Control Statement for Natural Top-Down Structured Programming." Symp. on Programming Languages. Paris, 1974): begin quit on event1 if (cond1) { [...A...] /* lots of code */ raise event1;} else if (cond2) { raise event1; } then event1: [...B...] /* lots more code */ end In this case, the sequence between "begin" and "then" is executed once (or until a named event arises). If no even arises, the part between "then" and "end" is simply skipped. If a named event arises (they all must be listed on the "begin" line and each must have a handler in the "then" part) the corresponding event handler is executed and the program continues with whatever follows "end". I don't like this as well as I do GOTOs. In the Nemesis programming language, the words "begin" and "end" have no flow-control meaning. They are instead used, entirely, to allow local restrictions on scope. So: Begin ! exclamation point is comment marker Import all ! bring in all outside declarations If (cond1) then ![...A...] stands for lots of code Goto 1 Else if (cond2) then 1 continue ! label may only appear on a no-op statement ![...B...] stands for lots more code Endif End This limits the scope on the statement label '1' in such a way that it can't be jumped to from outside the begin-end block. IMHO this provides the correct level of control over how GOTO is used without unduely constraining the programmer or obscuring the program. Of course, Nemesis doesn't _require_ that you limit the visability of labels this way, nor does it restrict _where_ a label may occur. But, there's only so much hand-holding a language can provide.