gpt4 book ai didi

c - size_t 0x1<<31 比 size_t 0x1<<30 大很多

转载 作者:太空狗 更新时间:2023-10-29 15:13:00 27 4
gpt4 key购买 nike

我对 size_t 的某些行为感到困惑我注意到:

size_t zero = 0x1 << 32;
size_t big = 0x1 << 31;
size_t not_as_big = 0x1 << 30;
printf("0x1<<32: %zx\n0x1<<31: %zx\n0x1<<30: %zx\n", zero, big, not_as_big);

结果:

0x1<<32: 0
0x1<<31: ffffffff80000000
0x1<<30: 40000000

现在,我明白了 size_t只保证至少是 16 位无符号整数,但我不明白为什么 0x1<<31最终得到它所做的值 - 尝试分配 18 艾字节对我的程序做了一个数字。

我在 x86_64 上使用 LLVM。

最佳答案

移动一个带符号的整数,使 1 进入符号位位置甚至更远在 C 中是未定义的,因此编译器可以自由地执行以下操作:

0x1 << 32

在这里,编译器看到一个 32 位 int (0x1),它被移动了 32 位。由于编译器可以自由地以与更正确的移位一致的方式对其进行解释,因此它将其解释为 0x1_0000_0000 并尝试将其转换为 32 位 int,从而产生 0x0000_0000,然后看到您稍后将结果分配给 size_t,通常是 64 位:0x0000_0000_0000_0000

0x1 << 31

和以前一样,编译器可以自由地做任何它认为正确的事情,因为 1 位侵入了符号位位置。所以结果是 0x8000_0000,这是一个负数 - 准确地说是 INT_MIN。然后,它看到您将该负数转换为 64 位,因此它用 1 扩展它,就像所有负数一样。结果是 0xffff_ffff_8000_0000,这是存储为带符号 64 位整数的最小 32 位带符号整数。

在所有 64 位平台之间正确且可移植的方法是:

((size_t)1) << 32
((size_t)1) << 31

关于c - size_t 0x1<<31 比 size_t 0x1<<30 大很多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21790665/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com