将 32 位整数复制到 64 位整数是未定义的吗?
Copying a 32 bit integer to a 64 bit integer is undefined?
好吧,我知道 << 32
在 32 位整数上是未定义的...我也知道指针转换和取消引用不会混合太多。
但这一个是其中的一种 none。
test.c:
#include <stdio.h>
#include <stdlib.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
int main(void)
{
uint64_t tmp = 1 << 31;
printf("%" PRIx64 "\n", tmp);
return 0;
}
然后我这样做:
$ gcc test.c -o test
$ ./test
ffffffff80000000
为什么它损坏了前 4 个字节?
低班工作正常。
如果我这样做 printf("%x\n", 1 << 31)
,它会按预期产生 80000000。
如果 tmp 是 32 位,它也可以正常工作。
u64
和 __u64
也有这个怪癖。
您没有损坏任何东西,但您也没有移动 64 位数字。在 C 中,单个 1
默认为 int
。如果您想将 1
用作 unsigned long
(或 unsigned
),请通过在数字后缀添加 (UL
或 U
-- (ULL
on x86)),否则你正在移动一个带符号的数字:
uint64_t tmp = 1ULL << 31;
输出
80000000
好吧,我知道 << 32
在 32 位整数上是未定义的...我也知道指针转换和取消引用不会混合太多。
但这一个是其中的一种 none。
test.c:
#include <stdio.h>
#include <stdlib.h>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
int main(void)
{
uint64_t tmp = 1 << 31;
printf("%" PRIx64 "\n", tmp);
return 0;
}
然后我这样做:
$ gcc test.c -o test
$ ./test
ffffffff80000000
为什么它损坏了前 4 个字节?
低班工作正常。
如果我这样做 printf("%x\n", 1 << 31)
,它会按预期产生 80000000。
如果 tmp 是 32 位,它也可以正常工作。
u64
和 __u64
也有这个怪癖。
您没有损坏任何东西,但您也没有移动 64 位数字。在 C 中,单个 1
默认为 int
。如果您想将 1
用作 unsigned long
(或 unsigned
),请通过在数字后缀添加 (UL
或 U
-- (ULL
on x86)),否则你正在移动一个带符号的数字:
uint64_t tmp = 1ULL << 31;
输出
80000000