意外的左移行为

sim*_*mon 5 c bit-shift

可能重复:
GCC左移溢出

考虑以下最小程序.

#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;
}
Run Code Online (Sandbox Code Playgroud)

这打印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;
}
Run Code Online (Sandbox Code Playgroud)

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

Ry-*_*Ry- 7

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


Dan*_*her 6

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