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@xxxxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxxxx> 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.