使用 size_t 初始化循环变量时整数下溢
Integer Underflow when initializing for loop variable with size_t
我是 运行 下面的代码示例,最初尝试向后打印字符数组,其中 count
表示数组中的字符数。每次我 运行 for 循环时,i
都没有被初始化为 count - 1
而是被初始化为一些非常大的数字。但是在循环之外,我被正确地初始化为 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
"unsigned" 整数没有符号且始终为非负数。如果您在 i = 0
上执行 --i
,那么您将获得 std::size_t
的最大值。
改为这样做:
// iterates from (count - 1) to 0
for (std::size_t i = count; i--;)
那么这是如何工作的呢? i--
是后缀递减运算符,returns 是 i
的先验值。这样,循环条件实际上是将 count, ..., 1
与零进行比较,而在循环中我们得到 count - 1, ..., 0
.
这个成语的一个更通用的版本有时被称为 -->
operator:
// iterates from (high - 1) to low
for (std::size_t i = high; i-- > low;)
std::size_t
是无符号整数类型。所以类型的值永远不会是负数。
像这样重写循环
std::size_t i {count - 1};
do
{
std::cout << i << std::endl;
} while ( i-- );
首先,外部作用域中的 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';
}
我是 运行 下面的代码示例,最初尝试向后打印字符数组,其中 count
表示数组中的字符数。每次我 运行 for 循环时,i
都没有被初始化为 count - 1
而是被初始化为一些非常大的数字。但是在循环之外,我被正确地初始化为 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
"unsigned" 整数没有符号且始终为非负数。如果您在 i = 0
上执行 --i
,那么您将获得 std::size_t
的最大值。
改为这样做:
// iterates from (count - 1) to 0
for (std::size_t i = count; i--;)
那么这是如何工作的呢? i--
是后缀递减运算符,returns 是 i
的先验值。这样,循环条件实际上是将 count, ..., 1
与零进行比较,而在循环中我们得到 count - 1, ..., 0
.
这个成语的一个更通用的版本有时被称为 -->
operator:
// iterates from (high - 1) to low
for (std::size_t i = high; i-- > low;)
std::size_t
是无符号整数类型。所以类型的值永远不会是负数。
像这样重写循环
std::size_t i {count - 1};
do
{
std::cout << i << std::endl;
} while ( i-- );
首先,外部作用域中的 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';
}