[comp.sys.sun] Bug in compilers

luke@research.canon.oz.au (Luke Kendall) (06/28/91)

I posted an article describing a `bug' in the GNU and Sun C compilers,
(shifts by an amount greater than the number of bits in the thing
being shifted, not producing a zero result).

Various people have pointed out to me that this is ok: K&R state that
the behaviour of a shift in this instance is undefined.

However, I'm posting this followup since some people seem to think that
this is still true in ANSI C.  It's not.  In the Language section, 3.3.7:

   "The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
    bits are filled with zeros.  If E1 has an unsigned type, the value
    of the result is E1 multiplied by the quantity, 2 raised to the power
    E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1
    otherwise. ..."

Provided U...MAX+1 is a power of 2, and calling N the number of bits in
a long, this means that we take an integer n * 2^N and reduce it mod 2^N:
i.e. we get zero.   Similarly for left shift:

   "The result of E1 >> E2 is E1 right-shifted E2 bit positions.  If E1
    has an unsigned type or if E1 has a signed type and a nonnegative
    value, the value of the result is the integral part of the quotient
    of E1 divided by the quantity, 2 raised to the power E2.  If E1 has
    a signed type and a negative value, the resulting value is
    implementation-defined."

That is, we notionally divide and drop the fraction; for large shifts, then,
this produces a zero.

So presumably the Sun ANSI compiler (and the GNU compiler if it is to be
considered ANSI compliant) will correct this feature of the language and
so change the behaviour of my `shift' program so that, in my opinion, it
will behave sensibly.
-- 
Luke Kendall, Senior Software Engineer.      | Net:   luke@research.canon.oz.au
Canon Information Systems Research Australia | Phone: +61 2 805 2914
P.O. Box 313 North Ryde, NSW, Australia 2113 | Fax:   +61 2 805 2929