This is the mail archive of the gcc@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: warning: right shift count >= width of type


>> On Nov 29, 2004, at 10:51 AM, Andrew Haley wrote:
>>> I myself would want "(n >> 32)" to produce the same result as "((n >> 16)
>>> 16)" and indeed "for (int i = 32; i > 0; i--, n >>= 1) ;", and it seems
>>> to be generally agreed that the compiler would be at liberty to so do if
>>> it wants to.
>>
>> But you could never depend on it.  If it only works when the shift
>> count is a constant, a failure to do constant folding would break it.
>
> Or constant propagation, or inlining, or ...

Would think that if GCC wants to define an equivalence between:

 (x * <pow2>) == (x << (log2 <pow2>))

and/or

 (x / <pow2>) == (x >> (log2 <pow2>))


And generally algebraically manipulate such expressions:

 (x * <pow2-a>) * (y >> z) / <pow2-b>

=> 

 (x * y) << (+ z (- <pow2-a> <pow2-b>))
or
 (x * y) >> (+ z (- <pow2-a> <pow2-b>))


It likely needs to define what (x << z) means if:

- z lesser-or-equal-to 0, [i.e. does (x << -1) == (x >> 1) ?]

- z greater-or-equal-to bit-size-of( x * z )
  [i.e. does (x * <pow2-bits-in-x>) == (x << (log2 <pow2-bits-in-x>)) ?]

Regardless of what the "less than concise" C standard says, or the
assumption of such equivalences are fragile.






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