switch (expression)

Tom Stockfisch tps at chem.ucsd.edu
Thu Jul 14 18:15:31 AEST 1988


In article <1988Jul12.105547.13268 at light.uucp> bvs at light.UUCP (Bakul Shah) writes:
>dpANS says the expression in ``_s_w_i_t_c_h (expression)''
>must be an integer valued expression.  Any chance of
>getting this changed ``must be an integer or ptr valued
>expression''?  The current restriction forces one to use
>the messier and longer sequence of ``if..then..else if
>...'' for pointers.  That is, instead of
>
>	switch (ptr)
>	{
>	case PTR1:
>		foo; bar1; break;
>	case PTR2: case PTR3:
>		foo; bar2; break;
>	default:
>		foo; barx; break;
>	}

The problem is not the ptr expression, it's the PTR* constants.
In the original
K&R, this was disallowed.  There are different classes of constants in C --
some are more "constant" than others.  Initialization constants can be
addresses of static or extern variables, but case constants must be 
arithmetic constants, possibly involving non-cast operators.  See Appendix
A, sec 15.  The reason for the constraint is that usually the linker
assigns the actual addresses to variables:  the compiler can't know
their value, and the situation is just as if you tried to do

	int	i;
	switch( expr )
	{
	case i:
	...
	}

>the following must be used:
>
>	if (ptr == PTR1) {
>		foo; bar1;
>	} else if (ptr == PTR2 || ptr == PTR3) {
>		foo; bar2;
>	} else {
>		foo; barx;
>	}

Them's the breaks.

>Note that the switch stmt can be used by casting the ptr
>to a long or an int, but I don't know if this is safe on
>all architectures -- (casts) should be avoided where
>possible.

You can cast "ptr" just fine, but neither the constant addresses
nor casts can appear in the case constructs.

>Could it be that even though K&R1 forbade mixing ints
>with ptrs and specified that only integer expression be
>used in a switch expression, all old compilers continued
>to treat the switch expression `sensibly' AND _somehow_
>the committee overlooked this?
>-- Bakul Shah <..!{ucbvax,sun,uunet}!amdcad!light!bvs>

Our Berkeley compiler would not compile this, and gave the interesting
diagnostic "duplicate case in switch" for the following code:

	extern int	*ptr, a, b, c;

	switch( ptr )
	{
	case	a:
		...
	case	b:
		...
	case	c:
		...
	default:
		...
	}

The explanation for the diagnostic is that the compiler inserted the null
pointer as a place holder for all unresolved extern address references,
so that all three cases wound up being the same (zero) when the compiler
went to create the jump table.

-- 

|| Tom Stockfisch, UCSD Chemistry	tps at chem.ucsd.edu



More information about the Comp.std.c mailing list