在 C 中,当左侧操作数为负值时,按位左移操作调用未定义行为。
来自 ISO C99 (6.5.7/4) 的相关引用
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 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
但在 C++ 中,行为是明确定义的。
ISO C++-03 (5.8/2)
The value of E1 << E2 is E1 (interpreted as a bit pattern) left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 multiplied by the quantity 2 raised to the power E2, reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1 otherwise. [Note: the constants ULONG_MAXand UINT_MAXare defined in the header ). ]
意思是
int a = -1, b=2, c;
c= a << b ;
在 C 中调用未定义行为,但该行为在 C++ 中已明确定义。
是什么迫使 ISO C++ 委员会认为这种行为与 C 中的行为相反?
另一方面,当左操作数为负时,行为是实现定义
按位右移操作,对吧?
我的问题是为什么左移操作调用 C 中的未定义行为,为什么右移操作符只调用实现定义的行为?
P.S:请不要给出“这是未定义的行为,因为标准是这样说的”这样的答案。 :P
最佳答案
您复制的段落是关于无符号类型的。行为是在 C++ 中未定义。来自上一个 C++0x 草案:
The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
编辑:看看 C++98 论文。它根本没有提到签名类型。所以它仍然是未定义的行为。
右移负数是实现定义的,对。为什么?在我看来:实现定义很容易,因为左边的问题没有截断。当您向左移动时,您不仅必须说出从右侧移动的内容,还必须说出其余位发生的情况,例如用二进制补码表示,这是另一回事。
关于c++ - 为什么当左侧操作数为负值时,左移操作会调用未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3784996/