undefined behavior when left operand is negative
3down voteaccepted

The rules haven't changed. It's still technically undefined.

Quoting from the C standard (Section 6.5.7, paragraph 4, of n1548):

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.

It clearly says if E1 is not unsigned or signed with nonnegative value, the behavior is undefined.


中文解释一下:

E1 << E2,如果E1不是一个无符号数,且不是非负数,也就是说当E1是负数时,行为是未定义的。


C++03 standard tells us that the result of applying the bitwise shift operators to signed types can be UB and Impl. defined for negative values. My question is following: why for operator << it has undefined behaviour, while for operator >> it is just implementation defined ? Is there a strict reason why the result of << couldn't be implementation defined also ?
Thanks in advance.


Left shifting with a negative shift count

Signed integers on right-hand side are undefined behavior in the C language.

ISO 9899:1999 6.5.7 Bit-wise shift operators §3

The integer promotions are performed  on each of the operands. The type of  the result is that of the promoted  left operand. 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.

这个比较简单,不解释了。

splint会报错:

The right operand to a shift operator may be negative (behavior undefined).

实际上,对于右移也是一样的。


Noncompliant Code Example (Right Shift)

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 and may be either an arithmetic (signed) shift:

移位运算陷阱_result

or a logical (unsigned) shift:

移位运算陷阱_result_02


参考:

https://www.securecoding.cert.org/confluence/display/cplusplus/INT34-CPP.+Do+not+shift+a+negative+number+of+bits+or+more+bits+than+exist+in+the+operand