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


Dave Korn writes:
 > > -----Original Message-----
 > > From: Dale Johannesen 
 > > Sent: 29 November 2004 16:31
 > 
 > > On Nov 29, 2004, at 8:18 AM, Dave Korn wrote:
 > > >   Afternoon all.  Here's something that's piqued my curiosity; it's 
 > > > probably
 > > > owing to some language-lawyerly issue, but it isn't obvious to me.  
 > > > This is
 > > > on gcc-3.3.3, (cygwin variant, but that's probably not relevant):
 > > >
 > > > -------------------------<snip!>-------------------------
 > > > dk@mace /test/shift-test> cat foo.c
 > > >
 > > > unsigned int bar (unsigned int baz)
 > > > {
 > > > unsigned int quux;
 > > >
 > > >         quux = baz >> 32;
 > > >         return quux;
 > > > }
 > > >   Why isn't the shift operation optimised away and replaced with 
 > > > const_int
 > > > 0?
 > > 
 > > Because that's not what it means.  Shifts by >= word size are 
 > > undefined 
 > > behavior
 > > and will give different results depending on optimization 
 > > level and on 
 > > whether
 > > the shift count is constant or variable.  Don't do that.  (If 
 > > you think 
 > > it ought to be 0,
 > > reflect that most popular CPUs have only 5 bit shift counts, and 
 > > consider what the
 > > code for x >> y would have to look like.)
 > 
 > 
 >   Absolutely so; my curiosity was piqued when I noticed that my
 > cross-compiler was generating illegal assembler code with an out-of-range
 > operand value that the assembler couldn't fit into the relevant opcode
 > bitfield.
 > 
 >   So my question is really "Given that it's undefined, which means that
 > whatever the compiler does is correct, and given that there's already code
 > in there to detect the situation and issue a warning, which probably means
 > that it would be very easy at such a point to replace the offending RTL with
 > (const_int 0), is there any specific reason why not to?"

I think the idea is that 

  a << n  /* n == 32 */

and 

  a << 32

should do the same thing.  This seems IMO more helpful than
optimizing away the shift.

 >   I imagine that this is one of those areas where "undefined
 > behaviour" is the standard's way of saying "Well, some compilers in
 > the past got it right and some got it wrong and since the standard
 > is largely about codifying the de-facto behaviour of existing C
 > compilers we'll leave this one alone",

No, not at all.  The x86 processors interpret this as 

  a << (n % 32)

 > but it's surely only an issue of bugward-compatibility:
 > mathematically, there's really no problem with right-shifting more
 > than the width of the integer, all that happens is that _all_ the
 > bits drop out the right-hand side and you're left with nothing.

That's not what all hardware actually does with shift instructions.

 > ISTM reasonable that the result of a right-shift by 32 bits could
 > be assumed to be the same thing you get if you right-shift by 1 bit
 > 32 times....

The chip designers don't agree.

Andrew.


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