【问题标题】:Integer Underflow when initializing for loop variable with size_t使用 size_t 初始化 for 循环变量时的整数下溢
【发布时间】:2019-09-14 13:21:57
【问题描述】:

我正在运行下面的代码示例,最初尝试向后打印一个字符数组,其中count 表示数组中的字符数。每次我运行 for 循环时,i 都没有初始化为 count - 1,而是初始化为一个非常大的数字。但在循环之外,i 被正确初始化为 4。我无法解释为什么会发生这种情况。

size_t count {5};
size_t i {count - 1UL}; // i is initalized to 4

for(size_t i {count - 1}; i >= 0UL; --i) {
    std::cout << i << std::endl;
} // infinite loop, i is initalized to 18446744073709141874

【问题讨论】:

标签: c++ loops for-loop unsigned size-t


【解决方案1】:

“无符号”整数没有符号且始终为非负数。如果你对i = 0 执行--i,那么你将得到std::size_t 的最大值。

改为这样做:

// iterates from (count - 1) to 0
for (std::size_t i = count; i--;)

那么这是如何工作的呢? i-- 是后缀递减运算符,它返回 i 的先验值。这样,循环条件实际上是将count, ..., 1 与零进行比较,而在循环中我们得到count - 1, ..., 0

这个成语的更通用版本有时称为--&gt; operator

// iterates from (high - 1) to low
for (std::size_t i = high; i-- > low;)

【讨论】:

  • 现在读起来很完美:-)
【解决方案2】:

首先,外部作用域中的i 未使用并带有阴影,其次,无符号整数始终大于或等于0。只要你打开compiler warnings,你就可以让你的编译器检测到这些:

<source>:7:38: error: comparison of unsigned expression >= 0 is always true [-Werror=type-limits]

    7 |     for(std::size_t i {count - 1}; i >= 0UL; --i) {

      |                                    ~~^~~~~~

<source>:5:17: error: unused variable 'i' [-Werror=unused-variable]

    5 |     std::size_t i {count - 1UL}; // i is initalized to 4

      |

解决方案:

for (unsigned long long i = 4ull; i != -1ull; --i) {
    std::cout << i << '\n';
}

【讨论】:

    【解决方案3】:

    std::size_t 是无符号整数类型。所以类型的值永远不会是负数。

    像这样重写循环

    std::size_t i {count - 1};
    
    do
    {
        std::cout << i << std::endl;
    } while ( i-- );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 2011-04-02
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      相关资源
      最近更新 更多