Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!ll-xn!mit-eddie!husc6!cca!g-rh From: g-rh@cca.CCA.COM (Richard Harter) Newsgroups: comp.lang.c Subject: Re: Duff's device Message-ID: <32941@cca.CCA.COM> Date: 3 Sep 88 10:23:14 GMT Reply-To: g-rh@CCA.CCA.COM (Richard Harter) Organization: Xerox Corporation, Cambridge, Massachusetts Lines: 63 Now I am a man that can write a goto without flinching and I can take structured programming or leave it, but Duff's device gives me the shudders. Granted that it may be guaranteed by the language specification. I have seen too many "broken" compilers that don't handle obscure technicalities correctly to be comfortable with "under such and such circumstances you may branch into a loop". Color me old-fashioned, but the idea gives me the creeps. Duff's device is another variant on the the loop and a half problem where you need to execute a loop body a whole number of times and part of the loop body once. His solution is (using goto's rather than a switch) is: goto A; do { code_section_1 A: /* Entry point for partial loop construction */ code_section_2 } while (sometest); Now all us good children know that when we write a loop with conditionals the compiler does some magic for us -- it creates some labels and transfers and tests and maybe does some block allocation. And it is incumbent upon us not to confuse the compiler. If I declare some variables at the start of the loop are they going to be there when I jump into the middle? This is the sort of code that you have to be a language lawyer to be sure that it works right -- and you have to assume that the compiler writer was a good language lawyer too. I don't like to write code that requires being a language lawyer to read and verify; life is too short. The besides of which, the device is not needed. If you are unrolling loops for speed the presumption is that you are willing to write duplicate code. You can always write code_section_2 do { code_section_1 code_section_2 } while (sometest); Or in the case in hand switch (remnant) { case 7: stuff; case 6: stuff; .... case 1: stuff; default: break; } for (;count;count--) { stuff; ... stuff; } It takes more lines of code, but it is a lot clearer, and it doesn't depend on obscurities of the language. Moreover it stands a better chance of executing faster on random compiler X. -- In the fields of Hell where the grass grows high Are the graves of dreams allowed to die. Richard Harter, SMDS Inc.