【问题标题】: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??

【问题讨论】:

    标签: c++


    【解决方案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 适合的最小允许类型,因此这是编译器使用的。
      猜你喜欢
      • 2017-11-28
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多