比特移位时的奇怪行为

cau*_*xic 5 c bit-manipulation

为什么下面用gcc编译的代码打印"ffffffff 0"而不是"0 0"?两个指令中的位向右移动了32个位置.它没有多大意义,因为x == 32,但仍然会发生这种奇怪的结果......

#include <stdio.h>

int main(void)
{
    int x = 32;
    printf("%x\n", 0xffffffff >> x);
    printf("%x\n", 0xffffffff >> 32);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑: 在此输入图像描述

编辑2:是的,编译器警告我.但这不是重点.我使用0xffffffff作为掩码,我用变量进行bithift.例如,当我使用8进行bithift时,我想要0xffffff(并且它会这样做).当我用31进行bithift时,我希望得到0x1(并且它会这样做).当我用32进行bithift时,它给了我0xffffffff(而不是0,当我有32作为文字,而不是变量时,这是beahaviour).这很奇怪,为了我的目的,为32创建一个特殊情况真的不方便,因为它应该给0(它确实如此,但只有当32是文字时)

250*_*501 6

假设int和unsigned int是32位宽,则整数常量0xffffffff的类型为unsigned int.

右移一个值大于或等于整数宽度的整数将导致未定义的行为1.

在您的示例中,这两种情况都会发生.

更新:

未定义的行为意味着任何事情都可能发生.获取值0xffffffff而不是0符合此行为.

您不能按整数类型的宽度移动,因为它在标准中表示如此.您必须检查该值是否大于或等于您使用的类型的宽度.


1(引用自:ISO/IEC 9899:201x 6.5.7按位移位运算符3)
如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.

  • @ caution2toxic这就是它未定义的原因.编译器可以随心所欲地完成. (4认同)