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?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 uint32_t 与 uint64_t 速度不同?

uint8_t / uint16_t / uint32_t /uint64_t数据类型详解

使用多个 uint32_t 整数生成 uint64_t 哈希键

uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型 - 大总结

uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是什么?

uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是什么?