[net.lang.c] switch.and.case

dwm@pur-ee.UUCP (Meeks) (05/31/84)

Let us get some serious discussion on this little piece of code:

main()
{
	int a,b;
	switch(a=6){
		b = a;
		if (b) {
			case '3' :
				printf("case three\n");
				break;
			case '6' :
				printf("case six\n");
				break;
			default:
				printf("error ... \n");
		}
		else {
			case '3' :
				printf("case three no b\n");
				break;
			case '6' :
				printf("case six no b\n");
				break;
			default:
				printf("not again ... \n");
				break;
		}
	}
}

okay folks, what really happens?

Tanks, Dan Meeks ... pur-ee!dwm

mab@druky.UUCP (BlandMA) (05/31/84)

x

I see two problems with the switch/case example:

	1. It doesn't even compile on System V because there are duplicate
	   cases in the switch statement.  K&R page 202 prohibits case
	   constants from having the same value.  Also, the line
	   following the switch statement is not reached since there
	   is no "case" preceding it.

	2. The author probably meant to use "case 6" rather than
	   "case '6'".  If this piece of code actually compiles on some
	   compiler, then the "default" case would be taken, instead of
	   the "case 6" that the author probably intended.

A more interesting program that compiles on System V is
shown at the end of this article.  It demonstrates that a case can
jump into the middle of a block (something I never realized, but
is permitted by the K&R language definition).  It's not clear to me
what value j should have the first time - probably undefined.

			Alan Bland
			ihnp4!druky!mab
			AT&T-ISL Denver

main()
{
	int i;

	i=5;
	switch (3) {
	case 1:
		for (i=0; i<10; i++) {
			int j;
			j = i+1;
	case 3:
			printf("i=%d j=%d\n", i, j);
		}
		break;
	}
}

** program output on 3B20 **
i=5 j=0
i=6 j=7
i=7 j=8
i=8 j=9
i=9 j=10

matt@oddjob.UChicago.UUCP (Matt Crawford) (06/01/84)

What it does NOT do is compile, because of the duplicate
"case" tags.  Even without that problem, you'd go to the default
because 6 != '6'.  Why is this worth considering??  We have already
seen, from Tom Duff's contribution of 7-May-84, that a "switch"
will jump into the middle of a compound statement if you ask it to.
___________________________________________________
Matt			ARPA: crawford@anl-mcs.arpa
Crawford		UUCP: ihnp4!oddjob!matt

ron@brl-vgr.ARPA (Ron Natalie <ron>) (06/01/84)

Actually the construct

	case '6':

should compile on all compilers.  It's perfectly legal.

-Ron

ok@edai.UUCP (Richard O'Keefe) (06/13/84)

    My word, what a horrible piece of code!
My understanding is that "case <constant expr>:" and "default:"
are just as much like labels as they can possibly be.  The only
difference between the body of a switch and any other compound
statement is the way you (ugh) jump into it.  Think of it as a
GOTO label(expr); statement in PLurry/Idiotic.
    Best advertisement for Pascal I've ever seen (and I *like* C).

jim@hwcs.UUCP (Jim Crammond) (06/14/84)

We have a 32-bit "Orion" computer made by High Level Hardware and
I discovered a compiler bug when trying to put sendmail on it:

The offending C code was a switch statement in parseaddr.c of the form -

	switch (*rp)
	{
		register STAB *s;

	case MATCHCLASS:
	case MATCHNCLASS:
		s = stab(ap, ST_CLASS, ST_FIND);
		.......

This got compiled to something like:

	jump to the case selection code		/* switch */
	increase the local stack size		/* declaration */
label1:
label2: code for calling stab 			/* first case */
	.....
	case selection code
	.....

Anything (declarations or code) above the first case statement gets jumped over,
never to be executed. Thus the "increase the stack size" instruction
(n.b. its microprogrammed as a stack machine) was never executed and this had
the side effect that if the first statement of any case statement was a function
call, the first argument was lost and the second became the first etc.

Thus in the above example stab was called as "stab(ST_CLASS, ST_FIND, garbage)"

I would say that a declaration such as that above perhaps makes sense,
though I always prefer declarations to be at the beginning of routines,
but putting code before the first case is decidedly bad style.

It took a long time to track down this bug, compiler bugs are hard to find!
But this kind of code is obscure so that it's not really surprising that
no one had spotted it before.

If people avoided the type of code where you have to delve into the back of
K+R to find out its meaning, then a lot of time could be saved by others
who are trying to port it.

	- Jim Crammond

p.s. The Orion does not support signed characters - please don't use them
     in any code you want to distribute.