patches for Irix binutils 2.18 -- removal of some casts

Alan Modra amodra@bigpond.net.au
Thu Oct 23 00:29:00 GMT 2008


On Wed, Oct 22, 2008 at 11:48:10AM -0500, Michael Hennebry wrote:
> On Wed, 22 Oct 2008, Alan Modra wrote:
>> void foo (int count, void **p)
>> {
>>  while (--count >= 0)
>>    {
>>      long *q = *(long **)(--p);
>>      *p = 0;
>>      printf ("%p\n", q);
>>    }
>> }
>>
>> If you can't immediately spot the problem, you're not alone!
>
> Not knowing what it is supposed to do doesn't help either.

Clear an array of pointers and print their previous values.  At high
optimisation levels with loop unrolling, gcc generated code that
printed some zeros, even though the array was originally all non-zero.
In other words, the "*p = 0" assignment occurred before q had been
read for the corresponding array element.  This is not a gcc bug since
the above code has undefined behaviour according to the C standard.

> Supposing p is a pointer into an array of pointers
> to void and the pointers to void point to longs:
> The cast is unnecessary in C.

Yes.

> In C++, a statement should be: long *q = (long*)*(--p);

Agreed, this is the correct cast, if you must have one.

> In neither C nor C++ is a conversion from void**
> to long** guaranteed to produce a valid result.
> If void** and long** have different formats,
> evil is pretty much guaranteed.
> Is that what happened?

No, long** and void** had exactly the same representation.  Still
puzzled?

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list