On Tue, 2010-03-02 at 10:47 +0000, Andrew Haley wrote: 
> On 03/02/2010 10:34 AM, Pjotr Kourzanov wrote:
> 
> >> int duff4_fails(char * dst,const char * src,const size_t n)
> >> {
> >>   const size_t rem=n % 4, a=rem + (!rem)*4;
> >>   char * d=dst+=a;
> >>   const char * s=src+=a;
> >>   /* gcc bug? dst+=n; */
> >>   
> >>     switch (rem) {
> >>     case 0:  for(dst+=n;d<dst;d+=4,s+=4) {
> >>     /*case 0:*/    d[-4]=s[-4];
> >>     case 3:        d[-3]=s[-3];
> >>     case 2:        d[-2]=s[-2];
> >>     case 1:        d[-1]=s[-1];
> >>          }
> >>     }
> >>    return 0;
> >> }
> >> The first time around the loop the initializer (d+=n) is jumped around, so
> >> d == dst.  At the end of the loop, d+=4, so d > dst.  Therefore the loop
> >> exits.
> > 
> >   And its wrong since it shouldn't jump around the initializer.
> 
> Sure it should.  On entry to that loop, rem == 3.

  I agree, this is one of the places where referential transparency
breaks in C. I wouldn't have expected that the compiler could or 
would put the first expression before the switch in this case:

switch (rem) {
  for(dst+=n;d<dst;d+=4,s+=4) { 
case 0: d[-4]=s[-4]; ...
}}

However, the warning is still due, since a combination of a switch with a
for loop results in code that is completely ignored, i.e., is inaccessible. 
As I said, gcc-3.x used to issue a warning for this one...

> 
> Andrew.
> 


Reply via email to