我真的不理解以下代码发生了什么。为什么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??
我真的不理解以下代码发生了什么。为什么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??
decltype(MAXDWORD)
是比uint64_t
更窄的类型。因此表达式MAXDWORD + 1
也不是uint64_t
类型,而且在赋值给t3
之前会观察到unsigned
溢出行为。
t1 + 1
在uint64_t
类型中使用无符号算术进行计算,该类型较宽。
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 位表达式,但我知道你的意思。 - BathshebaMAXDWORD
是32位而不是64位,因为4294967295是32位无符号整数的最大值。MAXDWORD
只是定义了一个整数字面值的宏:#define MAXDWORD 0xffffffff
。正如你所看到的,没有指定类型后缀,并且32位无符号整数是允许的最小类型,可以容纳0xffffffff
,所以编译器使用了它。 - Remy Lebeau