Under GCC, the following code always return the left operand of <<
if num1s == 0
:
0xFFFFFFFFu << (32-num1s);
CoryKramer has answered why it is an undefined behavior by standard.
I'll try to expain how it works in the real situation. C++ compilers usually implement <<
and >>
operators for 32-bit integers as assembler instructions without checking the operand range. It means that the result depends on the processor-specific implementation of the shift instructions.
For example, Intel processor specification for 32-bit SHL/SHR/SAL/SAL instructions says:
The destination operand can be a register or a memory location. The count operand can be an immediate value or register CL. The count is masked to five bits, which limits the count range to 0 to 31.
It means that a << b
becomes a << (b & 0x1f)
on Intel processors. So shifting by 32 bits means no shift.
But you should not rely on this information! The compiler can also optimize the code and implement the shift operator using vector instructions. In this case, the behavior is unspecified even by processor specifications.
§5.8 Shift operators
The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
The value of
E1 << E2
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. IfE1
has an unsigned type, the value of the result isE1 × 2E2
, reduced modulo one more than the maximum value representable in the result type. Otherwise, ifE1
has a signed type and non-negative value, andE1×2E2
is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.