【问题标题】:Unexpected left-shift behaviour [duplicate]意外的左移行为[重复]
【发布时间】:2025-09-24 12:00:02
【问题描述】:

可能重复:
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 编译。因为 1 向左移动 32 次又是 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。有人可以解释这种行为吗?

【问题讨论】:

    标签: c bit-shift


    【解决方案1】:

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

    【解决方案2】:

    两者都是未定义的行为,因为移位距离必须小于类型的位宽。使用常量,gcc 的优化器会执行您期望的操作,但是使用变量,移位是在运行时完成的。可能移位距离被 31 掩盖了,所以没有移位,1 - 1 == 0。

    【讨论】:

      最近更新 更多