可能重复:
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
。有人可以解释这种行为吗?
答案 0 :(得分:7)
将32位值移位32位是C中未定义的行为。不要这样做。
答案 1 :(得分:6)
两者都是未定义的行为,因为移位距离必须小于类型的位宽。使用常量,gcc的优化器可以满足您的期望,但是使用变量,转换在运行时完成。可能移位距离被掩盖为31,因此不进行移位并且1 - 1 == 0。