Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.lang.c Subject: Re: generalized switch Message-ID: <2716@umcp-cs.UUCP> Date: Sun, 3-Aug-86 04:12:03 EDT Article-I.D.: umcp-cs.2716 Posted: Sun Aug 3 04:12:03 1986 Date-Received: Mon, 4-Aug-86 01:31:02 EDT References: <15093@ucbvax.BERKELEY.EDU> Reply-To: chris@maryland.UUCP (Chris Torek) Organization: University of Maryland, Dept. of Computer Sci. Lines: 78 In article <15093@ucbvax.BERKELEY.EDU> kos@ernie.Berkeley.EDU (Joshua Kosman) writes: >One of my only memories from a brief stint as a PL/I programmer years ago >was the pleasure of using a more general switch structure than C allows. [In particular, the compiler allowed `cases' that might have to be determined at run time, or at any rate were not simple constants.] >#define IS_TYPE_A(c) (c==this||c==that) >#define IS_TYPE_B(c) ((c==the_other||c==your_mother) && c != rambo) >and so on. Now what I need is > switch () { > IS_TYPE_A(c): > do_type_a(c); > break; > IS_TYPE_B(c): > do_type_b(c); > break; > } One of the key `features' in C is that most constructs have a very simple relationship to the machine code that will be generated for a given statement. switch `wants' to become a computed branch, much like the old FORTRAN GOTO (l1, l2, l3, ..., ln), var `switch' wins readability points over the computed GOTO, but not much else: it still requires constant expressions, so that the compiler can convert it back to one. In C, when one wants a run-time test, one must write a run-time test. In your particular example, you probably do not care how the test is implemented. Unfortunately (?), C requires you to care. This example appears to require run-time evaluation, but in another case (pardon the pun) you might be able to get away with this: #define IS_TYPEA(x) ((x) > 3 && (x) < 7) #define CASES_TYPEA case 4: case 5: case 6: #define IS_TYPEB(x) (!IS_TYPEA(x)) #define CASES_TYPEB default: You could then use if (IS_TYPEA(n)) { statements; } else if (IS_TYPEB(n)) { morestatements; } and switch (n) { CASES_TYPEA: statements; break; CASES_TYPEB: morestatements; break; } but not switch (n) { CASES_TYPEB: morestuff; break; /* default is to ignore */ } So this approach too has its pitfalls. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu