This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Infinite loop in dcraw with current GCC versions


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]