|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
In the Given below code Does case const-expression: do not have anny
effect on do ...while(); loop Thanks Pallav Singh #include<stdio.h> #include<stdlib.h> int main() { char to1[] ="Pallav"; char from1[] = "Puneet"; char *to = to1; char *from = from1; int count = 21; printf("Value in to is %s \n\n",to); printf("Value in from is %s \n\n",from); register n = (count + 7) / 8; /* count > 0 assumed */ switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); } printf("Value in to is %s \n\n",to); return 0; } |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Pallav singh wrote:
> In the Given below code Does case const-expression: do not have anny > effect on do ...while(); loop > > Thanks > Pallav Singh > > #include<stdio.h> > #include<stdlib.h> > > > int main() > { > > char to1[] ="Pallav"; > char from1[] = "Puneet"; > > char *to = to1; > char *from = from1; > int count = 21; > > printf("Value in to is %s \n\n",to); > printf("Value in from is %s \n\n",from); > > register n = (count + 7) / 8; /* count > 0 assumed */ > > switch (count % 8) > { > case 0: do { *to = *from++; > case 7: *to = *from++; > case 6: *to = *from++; > case 5: *to = *from++; > case 4: *to = *from++; > case 3: *to = *from++; > case 2: *to = *from++; > case 1: *to = *from++; > } while (--n > 0); > } > > printf("Value in to is %s \n\n",to); > return 0; > > > } > http://c-faq.com/misc/duff.html |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Pallav singh <singh.pallav@gmail.com> wrote:
> In the Given below code Does case const-expression: do not have anny > effect on do ...while(); loop I suggest you try to (a) modify the code so it can compile in C++, (b) modify the code so it actually does what you think it should do, then (c) step through the code in your debugger and see how it does it. BTW, this is a classic example of using unstructured code as a special case optimization, don't do this sort of thing by default. (Unstructured code is any code where there is a jump into or out of the middle of a loop or conditional.) > #include<stdio.h> > #include<stdlib.h> > > > int main() > { > > char to1[] ="Pallav"; > char from1[] = "Puneet"; > > char *to = to1; > char *from = from1; > int count = 21; > > printf("Value in to is %s \n\n",to); > printf("Value in from is %s \n\n",from); > > register n = (count + 7) / 8; /* count > 0 assumed */ > > switch (count % 8) > { > case 0: do { *to = *from++; > case 7: *to = *from++; > case 6: *to = *from++; > case 5: *to = *from++; > case 4: *to = *from++; > case 3: *to = *from++; > case 2: *to = *from++; > case 1: *to = *from++; > } while (--n > 0); > } > > printf("Value in to is %s \n\n",to); > return 0; > > > } |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
Pallav singh <singh.pallav@gmail.com> wrote in news:9b9df877-e28b-4170-
a27a-d3a21d90228e@b40g2000prf.googlegroups.com: > #include<stdio.h> > #include<stdlib.h> > > > int main() > { > > char to1[] ="Pallav"; > char from1[] = "Puneet"; > > char *to = to1; > char *from = from1; > int count = 21; > > printf("Value in to is %s \n\n",to); > printf("Value in from is %s \n\n",from); > > register n = (count + 7) / 8; /* count > 0 assumed */ > > switch (count % 8) > { > case 0: do { *to = *from++; > case 7: *to = *from++; > case 6: *to = *from++; > case 5: *to = *from++; > case 4: *to = *from++; > case 3: *to = *from++; > case 2: *to = *from++; > case 1: *to = *from++; > } while (--n > 0); > } > > printf("Value in to is %s \n\n",to); > return 0; > > > } > > A couple of notes: 1) The pointer 'from' is pointing out into the middle of nowhere so the value assigned into '*to' is semi random. 2) The above loop boils down to: int m = count % 8; if (m == 0) m = 8; from += m + (n-1) *8; *to = *(from -1); I would think this would be a bit more efficient, if just as odd as the above. You still have the out of bound memory access problem. joe |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Jan 2, 3:32 pm, Joe Greer <jgr...@doubletake.com> wrote:
> Pallav singh <singh.pal...@gmail.com> wrote in > news:9b9df877-e28b-4170- > a27a-d3a21d902...@b40g2000prf.googlegroups.com: > > #include<stdio.h> > > #include<stdlib.h> > > int main() > > { > > char to1[] ="Pallav"; > > char from1[] = "Puneet"; > > char *to = to1; > > char *from = from1; > > int count = 21; > > printf("Value in to is %s \n\n",to); > > printf("Value in from is %s \n\n",from); > > register n = (count + 7) / 8; /* count > 0 assumed */ > > switch (count % 8) > > { > > case 0: do { *to = *from++; > > case 7: *to = *from++; > > case 6: *to = *from++; > > case 5: *to = *from++; > > case 4: *to = *from++; > > case 3: *to = *from++; > > case 2: *to = *from++; > > case 1: *to = *from++; > > } while (--n > 0); > > } > > printf("Value in to is %s \n\n",to); > > return 0; > > } > A couple of notes: > 1) The pointer 'from' is pointing out into the middle of nowhere so the > value assigned into '*to' is semi random. > 2) The above loop boils down to: > int m = count % 8; > if (m == 0) m = 8; > from += m + (n-1) *8; > *to = *(from -1); > I would think this would be a bit more efficient, if just as odd as > the above. You still have the out of bound memory access problem. The code outside the switch is completely wrong, of course, but the switch itself is a very literal copy of Duff's device (where to pointed to what would today be a char volatile*). There are lots of possible variants, of course. The whole point of the exercise is that switch, in C++, really is a calculated goto with special labels. And although this example doesn't show it, there's also no requirement that the controled statement in a switch be a compound statement. Something like: switch ( count % 8 ) while ( count > 0 ) { case 0 : *to ++ = *from ++ ; case 7 : *to ++ = *from ++ ; case 6 : *to ++ = *from ++ ; case 5 : *to ++ = *from ++ ; case 4 : *to ++ = *from ++ ; case 3 : *to ++ = *from ++ ; case 2 : *to ++ = *from ++ ; case 1 : *to ++ = *from ++ ; count -= 8 ; } would also be perfectly legal. Another variant I've seen: switch ( *p ) { // ... case '.' : if ( isdigit( *(p + 1) ) ) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : scanFloatingPointConstant( p ) ; } else { case '~' : case '!' : case '%' : case '^' : // ... scanPunctuation( p ) ; } break ; // ... } There's no rule that all of the case labels have to be at the same level of nesting either. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> wrote in news:2c634276-e17c-470a-924d-
8c8684f4f75c@i29g2000prf.googlegroups.com: > > The code outside the switch is completely wrong, of course, but > the switch itself is a very literal copy of Duff's device (where > to pointed to what would today be a char volatile*). There are > lots of possible variants, of course. The whole point of the > exercise is that switch, in C++, really is a calculated goto > with special labels. And although this example doesn't show it, > there's also no requirement that the controled statement in a > switch be a compound statement. Something like: > > switch ( count % 8 ) > while ( count > 0 ) { > case 0 : > *to ++ = *from ++ ; > case 7 : > *to ++ = *from ++ ; > case 6 : > *to ++ = *from ++ ; > case 5 : > *to ++ = *from ++ ; > case 4 : > *to ++ = *from ++ ; > case 3 : > *to ++ = *from ++ ; > case 2 : > *to ++ = *from ++ ; > case 1 : > *to ++ = *from ++ ; > count -= 8 ; > } > > would also be perfectly legal. > > Another variant I've seen: > > switch ( *p ) { > // ... > case '.' : > if ( isdigit( *(p + 1) ) ) { > case '0' : case '1' : case '2' : case '3' : > case '4' : case '5' : case '6' : case '7' : > case '8' : case '9' : > scanFloatingPointConstant( p ) ; > } else { > case '~' : case '!' : case '%' : case '^' : > // ... > scanPunctuation( p ) ; > } > break ; > // ... > } > > There's no rule that all of the case labels have to be at the > same level of nesting either. > I would never say there is no use for such code, but I would want to be very sure that any code like that was truly required. You can easily run into traps where the code is actually slower because you are actually doing more work than just a straight forward calculation. Not to mention that any poor maintenance programmer who had to try to fix it would have a few hair pulling sessions before he figured it out (in my experience any way). Anyway, I was responding to the specific code, not the idea. joe |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Jan 3, 2:24 pm, Joe Greer <jgr...@doubletake.com> wrote:
> James Kanze <james.ka...@gmail.com> wrote in news:2c634276-e17c-470a-924d- > 8c8684f4f...@i29g2000prf.googlegroups.com: [...] > > Another variant I've seen: > > switch ( *p ) { > > // ... > > case '.' : > > if ( isdigit( *(p + 1) ) ) { > > case '0' : case '1' : case '2' : case '3' : > > case '4' : case '5' : case '6' : case '7' : > > case '8' : case '9' : > > scanFloatingPointConstant( p ) ; > > } else { > > case '~' : case '!' : case '%' : case '^' : > > // ... > > scanPunctuation( p ) ; > > } > > break ; > > // ... > > } > > There's no rule that all of the case labels have to be at the > > same level of nesting either. > I would never say there is no use for such code, but I would > want to be very sure that any code like that was truly > required. I didn't say I approved of it, jsut that I'd seen it:-). > You can easily run into traps where the code is > actually slower because you are actually doing more work than > just a straight forward calculation. Not to mention that any > poor maintenance programmer who had to try to fix it would > have a few hair pulling sessions before he figured it out (in > my experience any way). I've not seen this sort of thing for a long time now. Twenty years ago, with early C compilers, you could pretty much count on the compiler being naïve, and that such code would gain you a machine instruction or two. In the case of the original Duff's device, for example, Duff clearly said that he only implemented it because the other solutions had performance problems. On the other hand, you'll have to admit that such oddities can be amusing. (I like the IOCCC, too.) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
![]() |
| Outils de la discussion | |
|
|