Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!munnari.oz.au!goanna!ok From: ok@goanna.oz.au (Richard O'keefe) Newsgroups: comp.lang.c Subject: Re: problems/risks due to programming language, stories requ Message-ID: <2985@goanna.oz.au> Date: 16 Mar 90 02:47:39 GMT References: <1306@mindlink.UUCP> Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 70 In article <1306@mindlink.UUCP>, a563@mindlink.UUCP (Dave Kirsch) writes: > Do this in Pascal: > switch (i) { > case 2 : /* Add 2 to j */ > j++; > case 1 : /* Add 1 to j */ > j++; > case 0 : /* Print j out */ > printf("%d\n", j); > break; > default : > printf("Illegal value in switch.\n"); > abort(); > } Just for grins, I'll do it in C: if (i < 0 || i > 2) { printf("Illegal value %d in switch.\n", i); abort(); } j += i; printf("%d\n", j); More seriously, I have often run into the "this case is just like that only a bit different" problem several times. Trouble is, that with more than one minor variant, it is hard to make them all fall through. It can even be worth nesting your switches: switch (i) { case 1: case 2: case 3: switch (i) { case 1: ... ; break; case 2: ... ; break; case 3: ... ; break; } /* stuff common to cases 1, 2, and 3 */ break; ... and so on ... } If the cost of the extra switch() is a significant part of the cost of your program, you have an amazingly cheap program. The reason that I sometimes use this approach is that generally I don't *quite* want a fall-through exactly. Suppose I want case 1: i++; COMMON PART case 2: j++; COMMON PART To exploit fall-through here, I would have to use case 1: j--; i++; case 2: j++; COMMON PART which is *really* ugly and unmaintainable. The one case where I do regularly use fall-through without any trace of guilt is when "unwinding" side effects. E.g. { int state = 0; f = fopen(...); if (!f) goto ERROR; state = 1; p = malloc(...); if (!p) goto ERROR; state = 2; ... return OK_STATUS; ERROR: switch (state) { case 2: free(p); case 1: fclose(f); case 0: break; } return ERROR_CODE; }