[comp.os.minix] gotos

henry@utzoo.uucp (Henry Spencer) (09/30/89)

In article <24962@louie.udel.EDU> tweten@gilmore.nas.nasa.gov (Dave Tweten) writes:
>surely an absolute "No gotos" is not a defensable position.

I'd say it is, actually.  I haven't used one in years.  My experience is
that the temptation to use a goto is a sign that the code is poorly thought
out; the proper response (barring emergencies) is to rethink it.  Oddly
enough, when I do, the goto *invariably* goes away.
-- 
"Where is D.D. Harriman now,   |     Henry Spencer at U of Toronto Zoology
when we really *need* him?"    | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

kirkenda@psueea.uucp (Steve Kirkendall) (10/02/89)

In article <1989Sep29.183703.1275@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>In article <24962@louie.udel.EDU> tweten@gilmore.nas.nasa.gov (Dave Tweten) writes:
>>surely an absolute "No gotos" is not a defensable position.
>
>I'd say it is, actually.  I haven't used one in years.  My experience is
>that the temptation to use a goto is a sign that the code is poorly thought
>out; the proper response (barring emergencies) is to rethink it.  Oddly
>enough, when I do, the goto *invariably* goes away.

I use gotos about 5 times a year, writing application programs.  Mostly I use
them to break out of two or more levels of looping.  My favorite label names
are "BreakBreak" and "ContContCont".

I can't remember the last time I used a goto as anything except a multi-level
"break" or "continue" instruction.

But I won't let *anybody* tell me I'm wrong to use "goto BreakBreak" to break
out of embedded loops.  Some gotos *are* structured.

(BTW, the code that AST complained about was *not* this kind of goto.  It was
the spagetti kind.  Complaint about that goto was justified;  I only disagree
with the blanket "No Gotos" rule.)
	-- Steve Kirkendall
	      ...uunet!tektronix!psueea!jove!kirkenda
	or    kirkenda@cs.pdx.edu

peter@ficc.uu.net (Peter da Silva) (10/02/89)

In article <1764@psueea.UUCP>, kirkenda@psueea.uucp (Steve Kirkendall) writes:
> I can't remember the last time I used a goto as anything except a multi-level
> "break" or "continue" instruction.

There is one other condition where a goto is justified: in implementing a
state machine.

C is not the best language for implementing state machines, but still there
are three main approaches for doing the job. Each has its place:

(1) The big switch.

	This is what YACC and LEX use, and is appropriate for computer-
	generated state machines. There is no need for gotos here (yes,
	I know the standard yacc engine has gotos... it needn't).

(2) The subroutine approach.

	This is a good one for large human-generated state machines, where
	the majority of the code is in the states... not in the state
	machine. You basically do this:

		while( (*state)(...) != FINISHED )
			continue;

(3) The fast approach.

	If you need a really fast state machine, take a look at the typical
	big switch. The code looks like:

		while(state != FINISHED) {
			switch(state) {
				case STATE0: ...
					if(this) state = STATETHIS;
					else if(that) state = STATETHAT;
					else state = STATEELSE;
					break;
				...
			}
		}

	This is isomorphic with:

		STATE0:
			...
			if(this) goto STATETHIS;
			else if(that) goto STATETHAT;
			else goto STATEELSE;
		...

		FINISHED:

	A very good compiler could turn the one into the other, and a
	pretty good compiler would probably blow off optimising the
	latter. But for the sort of program that uses this (device driver,
	embedded processor) you tend not to trust optimisers anyway.

Now, I'm sure I'll be flamed to death for this. C'est la vie. It's an awfully
obscure situation, and in fact I've never written code like this myself. I have
seen it, though, and there really wasn't any alternative.
-- 
Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation.
Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-'
"That is not the Usenet tradition, but it's a solidly-entrenched            U
 delusion now." -- brian@ucsd.Edu (Brian Kantor)

jbeard@ntvax.uucp (Jeff Beardsley) (10/03/89)

Actually even the use of goto for a multi-level break/continue can easily
be avoided by taking the entire multi-level structure, making it into a 
function of its own, and using return.

This gets rid of the goto statement needed for multi-level break as well
as making the code more readable.  Therefore I believe the NO-GOTO blanket
statement *IS* a defensible position.

-- 
-------- Jeff Beardsley at UNT ----------- <jbeard@dept.csci.unt.edu> --------

tweten@gilmore.nas.nasa.gov (Dave Tweten) (10/04/89)

I hesitated before sending my original message on this issue because of
its potential for triggering more religious heat than intelectual
light.  I've been pleasantly surprised at the ratio of light to heat in
the responses, which has encouraged me to write my second and last
comment on the topic.

Several apparent believers in the "no gotos" faith responded to the
effect that in their experience "goto" had never been necessary to
express an algorithm; they had each gone for some long period of time
without ever having written one.  I agree.  It IS never necessary.  Any
algorithm can be expressed in C, using only linear code, "while" and
functions.  The rest of the control structures in the language,
including "goto", serve only to increase efficiency, clarity and
maintainability.

What is programming?  Clearly, I don't believe it is a religion.  In
spite of my job title, I don't believe it is science.  It is more
humanistic than mere mathematics.  It is more mundane than art (Donald
Knuth notwithstanding).  I prefer the notion of programming as craft,
with a shade of meaning somewhere between that of the AFL/CIO and of
the Actors Guild.  As a good craftsman, it is my responsibility to
possess and to know how to use a wide variety of tools of my trade.  I
must know their powers and their dangers.  I must know when the tool
fits the problem and when it doesn't.

Several respondents adequately covered the uses of "goto" which amount
to a multi-level "break".  What follows is an explanation of why I think
"goto" works well for the third example in my original message, breaking
out of a single loop without executing the loop exhaustion code.  The
"gotofull" form is:

		while (<still looking>) {
			<do stuff>
			if (<we found it>) {
				<do foundit stuff>
				goto the_end;
			}
			<maybe do more stuff>
		}
		<do couldn't find it stuff>
	the_end:;

An obvious "gotoless" alternative is:

		while (<still looking>) {
			<do stuff>
			if (<we found it>) {
				<do foundit stuff>
				break;
			}
			<maybe do more stuff>
		}
		if (! <still looking>) {
			<do couldn't find it stuff>
		}

I prefer the form with the "goto", primarily for maintainability
reasons.  Introduction of extra condition tests increases the chance of
error and the difficulty of code analysis.  It becomes possible not
just to get it wrong, but also to get it inconsistent.  To my taste,
the second form is also less readable than the first.

Now, one could wrap the whole construct in a function and use an
embedded "return" statement, but that would be cheating.  Many of the
faithful regard imbedded returns as being equivalent to gotos and
exactly as sinful.  I agree.  Besides, except in the case of code which
should be set apart, either because it is a local option or because it
is in another language, I generally prefer not to write a function
unless it will be called from at least two places.

Dr. Tanenbaum's response was amusing.

From: Andy Tanenbaum <ast%CS.VU.NL@VM1.NoDak.EDU>

	I'll bet you like
	
	    i = 0;
	     <<VAX
	      some VAX assembly statements
	         XAV>>
	     j=0;
	     more C
	
While project leader for CDC's Cyber 200 FORTRAN '77 compiler and
library project (Fortran 200), I argued loudly (if unsuccessfully) that
in-line assembly code should not be carried over from the predecessor
FORTRAN '66 compiler.  I maintained that "Q8" in-line syntax converted
a good compiler into a bad assembler.  There is no doubt in my mind
that assembly code is occasionally the correct tool for the job.  The
"portable" way to use assembly code is to write separate assembler
source files.  That way a simple examination of the source file
directories will show what has to be rewritten for a new machine.  By
contrast, when there is in-line assembly a line-by-line examination of
all source files becomes necessary.

Incidently, try this for a REAL bit of heresy.  That project at CDC
offered me the second situation of only two in my 16-year programming
career in which instruction modification was the best tool for the job.
It was also the first in which my management permitted me to use it.
If you have it available, check the source code for FORTRAN 200's
"index" function in the case of a one-character pattern string.

But then, programming really ISN'T a religion, is it?

ok@cs.mu.oz.au (Richard O'Keefe) (10/04/89)

In article <1989Oct3.131847.15627@ntvax.uucp>, jbeard@ntvax.uucp (Jeff Beardsley) writes:
> Actually even the use of goto for a multi-level break/continue can easily
> be avoided by taking the entire multi-level structure, making it into a 
> function of its own, and using return.

> This gets rid of the goto statement needed for multi-level break as well
> as making the code more readable.  Therefore I believe the NO-GOTO blanket
> statement *IS* a defensible position.

The snag with this is that every variable which the formerly embedded
structure shared with its containing function now becomes a global
variable.  (In Pascal, "global" with respect to the new function; in
C, "global" in the sense of not local to any function, though perhaps
local to the file.)  You should be aware that global variables are a
maintenance problem in themselves; trading one goto for five globals
is rather like bending down to pick up 10 cents and dropping a dollar.

The answer is not to insert a goto and then patch it out by one or another
even more dubious dodge, but to follow a design method (such as the one
described by Dijkstra, Feijen, Gries, and others) where you never need a
goto or a multilevel loop exit in the first place.

henry@utzoo.uucp (Henry Spencer) (10/07/89)

In article <24984@louie.udel.EDU> tweten@gilmore.nas.nasa.gov (Dave Tweten) writes:
>Several apparent believers in the "no gotos" faith responded to the
>effect that in their experience "goto" had never been necessary to
>express an algorithm; they had each gone for some long period of time
>without ever having written one.  I agree.  It IS never necessary.  Any
>algorithm can be expressed in C, using only linear code, "while" and
>functions.  The rest of the control structures in the language,
>including "goto", serve only to increase efficiency, clarity and
>maintainability.

Except that careful thought yields those benefits without gotos.  The
theoretical adequacy of "while" is silly and irrelevant; we're talking
about practical coding.  The point is not that gotos can be avoided,
but that it is easy to do so and the results are better, not worse.
It's not hard to contrive examples where gotos are useful, it's just
that those examples seldom seem to show up in practice... and when they
do, careful thought generally seems to reveal deeper problems.

C News contains no gotos.   Geoff and I have received a number of compliments
on its clarity and maintainability.  And its efficiency approaches the
theoretical ultimate.
-- 
Nature is blind; Man is merely |     Henry Spencer at U of Toronto Zoology
shortsighted (and improving).  | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

tvf@cci632.UUCP (Tom Frauenhofer) (10/09/89)

My 2 cents on the goto argument:  The only times I have ever used a goto in
C was when I was in a rush and had to put a quicky fix into some code.
Whenever I go over the code later I invariably find a clearer way to write
the code without a goto.

I'm not anti-goto; I'm pro-readability.  I think goto's take away from the
readability of the code.  Continue statements are worse, especially when
you're an ex-FORTRAN hacker (boy, that'll stir up some controversy, won't
it? :-)

Thomas V. Frauenhofer	...!rutgers!rochester!cci632!ccird7!tvf
*or* ...!rochester!kodak!swamps!frau!tvf *or* ...!attctc!swamps!frau!tvf
"The Earth? I'm going to blow it up.  It obstructs my view of Venus" - Martin