Look at this sample C code (extracted a test case as an example):
main() {
unsigned long a, b;
int c;
c = 32;
a = 0xffffffff << 32;
b = 0xffffffff << c;
printf ("a=%x, b=%x\n", a, b);
}
Prints: a=0, b=ffffffff
I cannot understand why b is not zero, just like a. I tested this on Microsoft C and GCC.
Update: I fixed the stupid typo (should have been << c and not << b of course). But my question still stands, e.g. the result is still the same.
Description. This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.
C, however, has only one right shift operator, >>. Many C compilers choose which right shift to perform depending on what type of integer is being shifted; often signed integers are shifted using the arithmetic shift, and unsigned integers are shifted using the logical shift.
The bitwise shift operators move the bit values of a binary object. The left operand specifies the value to be shifted. The right operand specifies the number of positions that the bits in the value are to be shifted.
You never initialized b
to anything before you use it here:
b = 0xffffffff << b;
So it can be anything. (I think you actually meant to shift by c
.)
That aside:
The main issue is that shifting by the # of bits in the datatype or more is undefined behavior.
So if the literal 0xffffffff
is a 32-bit integer, then the line:
a = 0xffffffff << 32;
is not defined by the standard. (See comments.)
You should also be getting a compiler warning:
warning C4293: '<<' : shift count negative or too big, undefined behavior
In C it is undefined behavior to left shift more than the width of the promoted operand.
(C99, 6.5.7p3) "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."
I assume in the examples below int
and unsigned int
types are 32-bit.
The type of an unsuffixed hexadecimal integer constant is the first in the corresponding list in which its value can be represented: int
, unsigned int
, long
, unsigned long
, long long
, unsigned long long
.
So here 0xFFFFFFFF
is of type unsigned int
and 0xFFFFFFFF << 32
is undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With