Dear all,

  Although I probably shouldn't have been so harsh calling this
"mis-compiling", do you see any chance of back-porting this warning back
into the mainline? 

P.S. The rationale of this exercise is of course that the "switch",
being a goto in disguise needs careful attention, just like the goto.
So combining it a-la Tom Duff with another construct blessed by
Dijkstra, the for loop, can sometimes lead to unexpected results.

Pjotr

On Tue, 2010-03-02 at 14:07 +0100, Peter Kourzanov wrote: 
> On Tue, 2010-03-02 at 12:26 +0100, Richard Guenther wrote: 
> > On Tue, Mar 2, 2010 at 12:00 PM, Pjotr Kourzanov
> > <peter.kourza...@xs4all.nl> wrote:
> > > 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...
> > 
> > Neither 2.95 nor 3.3.6 or 3.4.6 warn for me.
> 
> That's weird. I am having:
> 
> gcc-3.3 (GCC) 3.3.6 (Ubuntu 1:3.3.6-15ubuntu6)
> Configured with: ../src/configure -v --enable-languages=c,c++
> --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info
> --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared
> --enable-__cxa_atexit --with-system-zlib --enable-nls
> --without-included-gettext --enable-clocale=gnu --enable-debug
> i486-linux-gnu
> Thread model: posix
> gcc-3.4 (GCC) 3.4.6 (Ubuntu 3.4.6-8ubuntu2)
> Configured with: ../src/configure -v --enable-languages=c,f77
> --prefix=/usr --libexecdir=/usr/lib
> --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared
> --with-system-zlib --enable-nls --without-included-gettext
> --program-suffix=-3.4 --enable-__cxa_atexit --with-tune=pentium4
> i486-linux-gnu
> Thread model: posix
> 
> Are you sure you test the following variant?
> 
> switch (rem) { 
> for(dst+=n;d<dst;d+=4,s+=4) {
>  case 0: d[-4]=s[-4]; ...
> }}
> 
> > 
> > Richard.
> > 
> > >>
> > >> Andrew.
> > >>
> > >
> > >
> > >
> > 
> 
> 


Reply via email to