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
- From: "Dave Korn" <dk at artimi dot com>
- To: "'Dale Johannesen'" <dalej at apple dot com>
- Cc: <gcc at gcc dot gnu dot org>,"'Andrew Haley'" <aph at redhat dot com>,"'Nathan Sidwell'" <nathan at codesourcery dot com>
- Date: Mon, 29 Nov 2004 16:59:28 -0000
- Subject: RE: warning: right shift count >= width of type
> -----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?" And it looks like
the answer is that there's no reason not to, but nobody has wanted to make
it work that way; it's historical accident rather than any kind of policy or
language issue.
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", 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. 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....
cheers,
DaveK
--
Can't think of a witty .sigline today....