uint64_t t3 = MAXDWORD + 1 == 0?

4

我真的不理解以下代码发生了什么。为什么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??
2个回答

11

decltype(MAXDWORD)是比uint64_t更窄的类型。因此表达式MAXDWORD + 1也不是uint64_t类型,而且在赋值给t3之前会观察到unsigned溢出行为。

t1 + 1uint64_t类型中使用无符号算术进行计算,该类型较宽。


3
在这种情况下,我认为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 位表达式,但我知道你的意思。 - Bathsheba
真的。我想我只是习惯了假设它是这样的。 - chasep255
在这种情况下,我认为MAXDWORD是32位而不是64位,因为4294967295是32位无符号整数的最大值。MAXDWORD只是定义了一个整数字面值的宏:#define MAXDWORD 0xffffffff。正如你所看到的,没有指定类型后缀,并且32位无符号整数是允许的最小类型,可以容纳0xffffffff,所以编译器使用了它。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接