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