patches for Irix binutils 2.18 -- removal of some casts

Michael Hennebry hennebry@www.cs.ndsu.nodak.edu
Thu Oct 23 16:45:00 GMT 2008


On Thu, 23 Oct 2008, Alan Modra wrote:

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

With a correct cast, all should have been well in either C or C++.
There might be a case in which I would convert void** to long**,
but I can't think of any at the moment.

>> 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?

No you gave me the answer.
The programmer used a wrong cast.
It hadn't occurred to me that the compiler would use
the undefinedness of a cast as an excuse to reorder code.

Was there a reason the programmer used pointer to long?
It seems to me that
void *q = *--p;
would have been correct, simpler and easier to think about.
If long* and void* have different formats,
printf is guaranteed to print long* incorrectly.

-- 
Michael   hennebry@web.cs.ndsu.NoDak.edu
"Pessimist: The glass is half empty.
Optimist:   The glass is half full.
Engineer:   The glass is twice as big as it needs to be."



More information about the Binutils mailing list