This should simply be adding 1 to an unsigned int: prev = nums[nextIndex + 1];
but it gives a warning saying
Arithmetic overflow: Using operator '+' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator '+' to avoid overflow
But I'm not using any 8 byte values, they are all 32-bit integers... Why is it casting stuff into 8 byte values for me?
I'm doing some questions on LeetCode so here is the full code for the question I'm working on, just rotating a vector of ints:
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
also gave the same warning and the only thing that got rid of it was casting everything to an unsigned int. I don't understand why it says I am using 8 byte values when I am definitely not using 8 byte values. I've ignored warnings like this in the past but LeetCode takes them very seriously. Thank you.
Vector indexes (and std::vector::size()
) are size_t
s, not unsigned int
s, and that's where your problems are coming from.
To fix this, declare all your unsigned int
variables as size_t
and get rid of all those casts:
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;
}
}
}
operator[]
in std::vector
is defined as
constexpr reference operator[]( size_type pos );
plus several similar overloads, all taking an argument of type size_type
defined by std::vector
. Cppreference.com says about this type this:
Unsigned integer type (usually std::size_t)
The explanation about std::size_t
(part):
std::size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, eg 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.
When indexing C++ containers, such as std::string, std::vector, etc, the appropriate type is the member typedef size_type provided by such containers. It is usually defined as a synonym for std::size_t.
So: std::vector
is indexed using a type that is usually equivalent to std::size_t
, which on your machine is a 64-bit unsigned int.
So, if you want the warning gone, you can define nextIndex
as a 64-bit unsigned integer, eg
unsigned long nextIndex
or size_t nextIndex;
std::vector<int>::size_type nextIndex;
or force the conversion by using a constant that is of type unsigned ling long
:
prev = nums[nextIndex + 1ull];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.