6.2.6.2/1 Integer types
The values of any padding bits are unspecified.45) A valid (non-trap) object representation of a signed integer type where the sign bit is zero is a valid object representation of the corresponding unsigned type, and shall represent the same value.
For any integer type, the object representation where all the bits are zero shall be a representation of the value zero in that type.
In the C99 standard, an integer type where all the bits are zero is guaranteed to represent the value 0
in that respective type. However, does this guarantee that the underlying binary value is what we expect it to be?
For example:
unsigned x = 42;
We'd normally expect a machine to store this decimal 42
value in memory as the binary 101010
value.
However, could some eccentric machine architecture store the same decimal 42
value as the binary 011011
value (not necessarily for a practical reason but simply because it can)?
If so, consider the following code utilizing a right shift operation:
unsigned y = x>>1; /* 101010>>1 or 011011>>1 */
Would y
hold the decimal value 21
(10101
in binary), or the decimal value 13
(01101
in binary)?
Does the C99 standard make any guarantee about the decimal representation of an unsigned integer type after a bitwise operation -- e.g. is a right shift guaranteed to be equivalent to an integer division by 2
on all machine architectures?
The representation of the integer isn't specified in the standard.
However, the behavior of >>
and <<
is defined according to the meaning of bits, not their position.
So >> 1
moves the bit representing 4 to the bit representing 2, regardless of where these bits actually are.
Quoting the C99 standard section 6.5.7:
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 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.