意外的左移行为

时间:2012-08-06 15:42:34

标签: c bit-shift

  

可能重复:
  GCC left shift overflow

考虑以下最小程序。

#include <stdint.h>
#include <stdio.h>

int main()
{
    uint32_t v = 1024;
    v &= (((uint32_t)1 << 32) - 1);
    printf("v = %u\n", v);
    return 0;
}

这会打印1024,因为我希望在MinGW下使用GCC进行编译。因为向左移动32次的1再次为0,因此0-1 = -1,即“1111 ...... 1111”。任何值的AND'应该再次返回相同的值。

但是,如果我将程序更改为

#include <stdint.h>
#include <stdio.h>

int main()
{
    unsigned int s = 32;
    uint32_t v = 1024;
    v &= (((uint32_t)1 << s) - 1);
    printf("v = %u\n", v);
    return 0;
}

现在打印的结果为0。有人可以解释这种行为吗?

2 个答案:

答案 0 :(得分:7)

将32位值移位32位是C中未定义的行为。不要这样做。

答案 1 :(得分:6)

两者都是未定义的行为,因为移位距离必须小于类型的位宽。使用常量,gcc的优化器可以满足您的期望,但是使用变量,转换在运行时完成。可能移位距离被掩盖为31,因此不进行移位并且1 - 1 == 0。