Edit: As pointed out below I missed the first part of the ANSI C standard: "If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." The errors (or rather lack of errors / difference in errors) are due to the particular compiler I was using.
I've come across something a bit strange, and I hope that someone can shed some light on my ignorance here. The necessary sample code is as follows:
#include <stdio.h>
int main(void)
{
unsigned a, b;
int w, x, y;
a = 0x00000001;
b = 0x00000020;
w = 31;
x = 32;
y = 33;
a << w; /*No error*/
a << x; /*No error*/
a << y; /*No error*/
a << 31; /*No error*/
a << 32; /*Error*/
a << 33; /*Error*/
a << 31U; /*No error*/
a << 32U; /*Error*/
a << 33U; /*Error*/
a << w + 1; /*No error*/
a << b; /*No error*/
return 0;
}
My question is this: why is it that an error is returned for a raw number, but not for any of the variables? They, I think, should be treated the same. According to the C11 standard
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.
The right side, since the left is unsigned type, should be 2^E2 reduced modulo one more than the maximum value representable in the result type.... That sentence isn't entirely clear to me, but in practice it seems that it is E1 << (E2%32) - despite that 32 is not the maximum representable in the result type. Regardless, it is not undefined for the C11 standard, yet the error
left shift count >= width of type [enabled by default]
shows up when trying to compile. I cannot deduce why it is that some values of >31 work (e.g. x = 33; a <
I am using the GCC compiler on 64-Bit Fedora. Thanks in advance. -Will
int
is a different size. – lrobb(E1 x 2^E2)%(2^32)
, since the integers are only 32 bits, hence the warnings. – Drew McGowena << w;
does nothing. Did you meana <<= w;
? – wildplasser