Hi,
I'm quite sure this has come up before, so apologies for the probably
repeated question. I checked all three technical corrigenda for C99, and
the latest C11 draft (N1570).
Please consider the following:
- unsigned short: 16 value bits, no padding bits,
- int: 1 sign bit, 31 value bits, no padding bits,
- long long: 1 sign bit, 63 value bits, no padding bits
#include <stdio.h>
int
main(void)
{
unsigned short x;
long long res;
x = 0xFFFF;
res = x << 16;
(void)fprintf(stdout, "%lld\n", res);
return 0;
}
In "x << 16", "x" is promoted to "int", which is also the result type (C99
6.5.7p3). The right operand is 16, which is non-negative and less than the
width of "int" (= 32, promoted left operand).
p4:
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 × 2^E2, reduced modulo one more than the maximum value
representable in the result type. If E1 has a signed type and
nonnegative value, and E1 × 2^E2 is representable in the result type,
then that is the resulting value; otherwise, the behavior is undefined.
E1 is "x" here, and it has an unsigned type. The result is 65535 * 2^16,
reduced modulo INT_MAX+1
(2147483648), that is, hexadecimal 7FFF0000.
Unless of course p4 means
<not actual standard language>
The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits
are filled with zeros. If E1 has an unsigned type *AFTER PROMOTION*,
the value of the result is E1 × 2^E2, reduced modulo one more than the
maximum value representable in the result type. If E1 has a signed
*PROMOTED* type and nonnegative value, and E1 × 2^E2 is representable in
the result type, then that is the resulting value; otherwise, the
behavior is undefined.
</not actual standard language>
In that case the program invokes undefined behavior.
"gcc -std=c99 -pedantic" on x86_64 RHEL-6.4 seems to agree with the latter
meaning, the program prints -65536.
What is the intent of the cited paragraph? I assume omitting "... after
promotion ..." was an oversight.
Thank you,
Laszlo