This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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.