Infinite loop in dcraw with current GCC versions

dcoffin@shell.cybercom.net dcoffin@shell.cybercom.net
Mon Mar 2 02:00:00 GMT 2015


     I fixed all the "undefined behavior" warnings with
typecasts, but I'm still getting array-bounds warnings
with manifestly correct code.  E.g. when blend_highlights()
uses the global variable "colors":

  static const float trans[2][4][4] = { ... }
...
  if ((unsigned) (colors-3) > 1) return;
...
  lab[i][c] += trans[colors-3][c][j] * cam[i][j];

     How could "colors-3" be out of bounds?  I just verified
that it's either 0 or 1, and if I hard-code 0 or 1 the warning
goes away.
				Dave Coffin  3/1/2015

On Sat, Feb 28, 2015 at 05:27:01PM +0100, Manuel López-Ibáñez wrote:
> On 27 February 2015 at 21:45,  <dcoffin@shell.cybercom.net> wrote:
> > Hi Manuel,
> >
> >      Yes, I know that cam_xyz[] would have to be declared
> > differently for *(cam_xyz + (i)*3 + (j)) to work, but it's
> > all the same at the hardware level.
> >
> >      If arrays are no longer pointers, but some sort of
> > abstract array-type, does ISO C allow them to be cast back
> > into pointers?  Something like:
> >
> > ((double *)(cam_xyz[0]))[j] = table[i].trans[j] / 10000.0;
> 
> cam_xyz[0] is type 'double [3]', thus I don't think you should cast it
> to 'double *', but in this respect I am just going by intuition, not
> by an actual reference to the standard. On the other hand,
> &cam_xyz[0][0] should have type 'double *', and the standard does say
> that the data is contiguously allocated, yet the c-faq says that
> ((double *)(&cam_xyz[0][0]))[j] "is not in strict conformance with the
> ANSI C Standard; according to an official interpretation"
> (http://c-faq.com/aryptr/ary2dfunc2.html), although without a
> reference to the standard, I have no idea what that means. In any
> case, I would be very wary of what anyone says unless they can really
> back it up with quotes from the standard.
> 
> Unfortunately, it seems that, at least GCC 4.8.2, generates different
> code if you use ((double *)(&cam_xyz[0][0]))[j] and one for-loop or if
> you use cam_xyz[i][j] and two for-loops. If the former is faster and
> valid, this really is a missed optimization bug worth reporting.
> 
> Cheers,
> 
> Manuel.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> >
> >                                 Dave Coffin  2/27/2015
> >
> > On Fri, Feb 27, 2015 at 09:08:50PM +0100, Manuel López-Ibáñez wrote:
> >> On 27 February 2015 at 20:02,  <dcoffin@shell.cybercom.net> wrote:
> >> > Manuel,
> >> >
> >> >      There is no "undefined behavior" here.  K&R defined it
> >> > very clearly:  Arrays are pointers, and square brackets are
> >> > syntactic sugar for pointer arithmetic and dereferencing:
> >> >
> >> >         cam_xyz[i][j]  vs.  *(cam_xyz + (i)*3 + (j))
> >>
> >> Unfortunately, this is simply not true for ISO C, which is the
> >> language that most compilers implement nowadays. And it is easy to
> >> check for yourself:
> >>
> >> test.c:445:27: error: incompatible types when assigning to type
> >> 'double[3]' from type 'double'
> >>   *(cam_xyz + (0)*3 + (j)) = table[i].trans[j] / 10000.0;
> >>                            ^
> >>
> >> See also the first answer to
> >> http://stackoverflow.com/questions/25139579/2d-array-indexing-undefined-behavior,
> >> which seems correct, AFAIU.
> >>
> >> Neither can you do: **(cam_xyz + (0)*3 + (j)), because cam_xyz has
> >> type 'double (*)[3]' thus **(cam_xyz + 2) is referencing
> >> cam_xyz[2][0].
> >>
> >> Cheers,
> >>
> >> Manuel.



More information about the Gcc-help mailing list