在C语言中,当左操作数为负值时,按位左移操作将会导致未定义的行为。
引用自ISO C99 (6.5.7/4):
E1 << E2 的结果是E1向左移动E2个二进制位,空出的位用0填充。如果E1的类型是无符号的,那么结果的值为E1乘以2的E2次方,然后对结果类型所能表示的最大值加1取余。如果E1是有符号类型并且非负,且E1乘以2的E2次方可以被结果类型所表示,则该值即为结果;否则行为未定义。
但在C++中,这种行为是定义明确的。
引用自ISO C++-03 (5.8/2):
E1 << E2的值就是将E1(解释为位模式)向左移动E2个二进制位,并用0填充空出的位。如果E1具有无符号类型,则结果的值为E1乘以2的E2次方,然后对ULONG_MAX+1取余(如果E1的类型是unsigned long),否则对UINT_MAX+1取余(注意:常量ULONG_MAX和UINT_MAX在头文件中定义)。
也就是说:
int a = -1, b=2, c;
c= a << b ;
在 C 中会触发未定义行为,但在 C++ 中该行为是被定义好的。
那么是什么促使 ISO C++ 委员会认为这种行为是好定义的呢?相比之下,当左操作数为负数时,位右移操作的行为是 “实现定义的”,对吗?
我的问题是,为什么左移操作会触发 C 中的未定义行为,而右移操作符只会引起“实现定义的”行为?
P.S:请不要给出像“这是未定义的行为,因为标准规定如此”这样的答案。:P