[英]Arithmetic overflow using all 32-bit ints in C++?
这应该只是将 1 添加到一个无符号整数: prev = nums[nextIndex + 1];
但它给出了警告说
算术溢出:对 4 字节值使用运算符“+”,然后将结果转换为 8 字节值。 在调用运算符“+”之前将值转换为更宽的类型以避免溢出
但我没有使用任何 8 字节值,它们都是 32 位整数......为什么它为我将东西转换为 8 字节值?
我正在做一些关于 LeetCode 的问题,所以这里是我正在研究的问题的完整代码,只是旋转一个整数向量:
void rotate(std::vector<int>& nums, int k) {
k %= nums.size();
if (k > 0) {
unsigned int offsetCounter = 0;
int prev;
int next = nums[0];
for (unsigned int i = 0; i < nums.size(); i++) {
int f = k * i;
unsigned int nextIndex = ((unsigned int)((unsigned int)k * ((unsigned int)i + (unsigned int)1)) + (unsigned int)offsetCounter) % (unsigned int)nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
nextIndex
也给出了相同的警告,唯一摆脱它的方法是将所有内容转换为 unsigned int。 我不明白为什么当我绝对不使用 8 字节值时它说我使用 8 字节值。 过去我忽略了这样的警告,但 LeetCode 非常重视它们。 谢谢你。
向量索引(和std::vector::size()
)是size_t
s,而不是unsigned int
s,这就是你的问题的来源。
要解决此问题,请将所有unsigned int
变量声明为size_t
并摆脱所有这些强制转换:
void rotate(std::vector<int>& nums, size_t k) {
k %= nums.size();
if (k > 0) {
size_t offsetCounter = 0;
int prev;
int next = nums[0];
for (size_t i = 0; i < nums.size(); i++) {
size_t nextIndex = (k * i + 1 + offsetCounter) % nums.size();
if (nextIndex == offsetCounter) {
offsetCounter++;
prev = nums[nextIndex + 1];
}
else
{
prev = nums[nextIndex];
}
nums[nextIndex] = next;
next = prev;
}
}
}
std::vector
operator[]
定义为
constexpr reference operator[]( size_type pos );
加上几个类似的重载,都采用std::vector
定义的size_type
类型参数。 Cppreference.com 是这样说的:
无符号整数类型(通常是 std::size_t)
关于std::size_t
的解释(部分):
std::size_t 通常用于数组索引和循环计数。 使用其他类型(例如 unsigned int)进行数组索引的程序在索引超过 UINT_MAX 或依赖于 32 位模算术时可能会在例如 64 位系统上失败。
在索引 C++ 容器时,例如 std::string、std::vector 等,适当的类型是此类容器提供的成员 typedef size_type。 它通常被定义为 std::size_t 的同义词。
所以: std::vector
使用通常等同于std::size_t
的类型进行索引,它在您的机器上是 64 位无符号整数。
因此,如果您希望警告消失,您可以将nextIndex
定义为 64 位无符号整数,例如
unsigned long nextIndex
或size_t nextIndex;
std::vector<int>::size_type nextIndex;
或使用unsigned ling long
类型的常量强制转换:
prev = nums[nextIndex + 1ull];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.