uint64_t t3 = MAXDWORD + 1 == 0?
Posted
技术标签:
【中文标题】uint64_t t3 = MAXDWORD + 1 == 0?【英文标题】:uint64_t t3 = MAXDWORD + 1 == 0? 【发布时间】:2018-11-05 10:25:52 【问题描述】:我真的不明白下面的代码发生了什么。为什么t3
为零?
uint64_t t1 = MAXDWORD; // t1 contains 4294967295 - CORRECT
uint64_t t2 = t1 + 1; // t2 contains 4294967296 - CORRECT
uint64_t t3 = MAXDWORD + 1; // t3 contains 0 (zero) - HUH??
【问题讨论】:
【参考方案1】:decltype(MAXDWORD)
是比uint64_t
更窄的类型。所以表达式MAXDWORD + 1
也不是uint64_t
,并且unsigned
环绕行为在分配给t3
之前观察到。
t1 + 1
使用uint64_t
类型在unsigned
算术中执行,该类型更宽。
【讨论】:
【参考方案2】:在这种情况下,我认为MAXDWORD
是 32 位而不是 64 位,因为 4294967295 是 32 位无符号整数的最大大小。因此,表达式MAXDWORD + 1
是两个 32 位值的总和,仅在评估后升级为 64 位。因此它将溢出回零。
t1 + 1
另一方面是 64 位和 32 位表达式。 32 位常量升级为 64 位,然后进行评估。因此这不会溢出。
试试下面的表达式,看看你能不能找出哪些会溢出……
uint64_t t4 = MAXDWORD + 1LL;
uint64_t t5 = (uint64_t)MAXDWORD + 1;
uint64_t t6 = MAXDWORD + (uint64_t)1;
uint64_t t7 = (uint64_t)(MAXDWORD + 1);
【讨论】:
文字1
不一定是32位表达式,但我知道你在说什么。
是的。我想我只是习惯于假设它是。
"在这种情况下,我认为 MAXDWORD
是 32 位而不是 64 位,因为 4294967295 是 32 位无符号整数的最大大小" - MAXDWORD
是只是一个定义integer literal:#define MAXDWORD 0xffffffff
的宏。如您所见,没有指定类型后缀,并且 32 位无符号整数是 0xffffffff
适合的最小允许类型,因此这是编译器使用的。以上是关于uint64_t t3 = MAXDWORD + 1 == 0?的主要内容,如果未能解决你的问题,请参考以下文章
uint8_t / uint16_t / uint32_t /uint64_t数据类型详解
使用多个 uint32_t 整数生成 uint64_t 哈希键
uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型 - 大总结