[comp.lang.c] Goto or not goto?

tif@commlab1..austin.ibm.com (/32767) (05/05/90)

In article <12866@ulysses.att.com> ggs@ulysses.att.com (Griff Smith) writes:
>How do you plan to debug your state machine?  If you have it filled
>with gotos, you have to follow each state transition the hard way.  If
>you use a switch on a state variable, you get to add code between the
>`for (;;)' and the switch to log state transitions, look for strange
>transitions, etc.  I think you're doing a disservice to mortals to
>encourage them to use idioms that are only manageable by higher forms of
>life.

Consider the following:

	#ifdef DEBUG
	#define STATE(x)	case x
	#define TO_STATE(x)	{state=x;break;}
	int	state;

	for(;;) {
		printf("Going to state %d\n", state);
		switch(state) {
	#else
	#define STATE(x)	lbl##x
	#define TO_STATE(x)	goto lbl##x
	#endif


		STATE(0):
			if (...) {
				...
				TO_STATE(0);
			} else
				TO_STATE(5);
		STATE(5):
			if (blah)
				TO_STATE(0);
		...


	#ifdef DEBUG
		}
	}
	#endif

I haven't tried compiling it and I don't know if I used the ## operator
correctly but I think you get the drift.  Now I put to you the question,
does this code suffer from the minuses of "goto" or have the advantages
of the "switch"?  I'm not saying I would write the code like this but
I think I'll let all of you think about how the previously stated pros
and cons apply to this code fragment.  (BTW, break won't work right easily
inside nested control structures.)

Paul Chamberlain
tif@doorstop.austin.ibm.com
tif@commlab1.austin.ibm.com
sc30661@ausvm6

richard@stat.tamu.edu (richard.henderson~) (05/07/90)

In article <2296@awdprime.UUCP> cs.utexas.edu!auschs!ibmaus!commlab1.austin.ibm.com!tif writes:
>In article <12866@ulysses.att.com> ggs@ulysses.att.com (Griff Smith) writes:
> [ Some neat defines and a little state machine deleted ]

After I saw this, I could not help but see what would happen, so I
wrote out a small state machine that matched (ab|c)*d.  It turned
out to produce 25% fewer lines of machine code under both cc (88 vs 120)
and gcc (74 vs 98) on a sun3.  And this seems right.  If I were
to hand code a state machine, it would have spaghetti jumps too.
I cannot see anything wrong with compiling with DEBUG to make
sure that it works, then turning it off.

Especially if it can speed up a simple pattern match on
/usr/dict/words by over 1 second.

>Paul Chamberlain
>tif@doorstop.austin.ibm.com
>tif@commlab1.austin.ibm.com
>sc30661@ausvm6

richard~
/*
   richard@csseq.tamu.edu
   richard@stat.tamu.edu
*/