2^32 - 1 不是 uint32_t 的一部分?

Sim*_*lbc 0 c uint32

这是编译输出让我哭的程序:

#include <inttypes.h>

int main()
{
        uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?
}
Run Code Online (Sandbox Code Playgroud)

这是编译输出:

~/workspace/CCode$ gcc uint32.c 
uint32.c: In function ‘main’:
uint32.c:5:29: warning: left shift count >= width of type [-Wshift-count-overflow]
         uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?
Run Code Online (Sandbox Code Playgroud)

我认为这(1 << 32) - 1等于 2^32 - 1 并且 32 位上的无符号整数范围从 0 到 2^32 - 1,是不是这样?我哪里做错了?

Fan*_*Fox 5

警告是正确的,32 位数字中的最高位是第 31 位(0 索引),因此溢出前的最大移位是1 << 30(30,因为符号位)。即使你-1在某个时候做的结果1 << 32必须被存储,它会被存储在一个int(在这种情况下恰好是 32 位)。因此,您会收到警告。

如果您真的需要获得最大值,则32 bit unsigned int应该以简洁的方式进行:

#include <stdint.h>

uint32_t limit = UINT32_MAX;
Run Code Online (Sandbox Code Playgroud)

或者更好的是,使用 c++ 限制头文件:

#include <limits>
auto limit = std::numeric_limits<uint32_t>::max();
Run Code Online (Sandbox Code Playgroud)