Path: utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!nosc!ucsd!chem.ucsd.edu!tps From: tps@chem.ucsd.edu (Tom Stockfisch) Newsgroups: comp.std.c Subject: Re: switch (expression) Message-ID: <253@chem.ucsd.EDU> Date: 14 Jul 88 08:15:31 GMT References: <1988Jul12.105547.13268@light.uucp> Reply-To: tps@chem.ucsd.edu (Tom Stockfisch) Organization: Chemistry Dept, UC San Diego Lines: 86 In article <1988Jul12.105547.13268@light.uucp> bvs@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@chem.ucsd.edu