This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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: patches for Irix binutils 2.18 -- removal of some casts


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


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