0

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.

3
  • Step 1: uses the same type in the addition nextIndex + 1 --> nextIndex + 1u (unsigned + int vs unsigned + unsigned). Perhaps the mixed addition hints to the complier you seek an arithmetic sum. Might as well simplify other code too: (unsigned int)1 --> 1u. Commented Jul 18, 2021 at 23:22
  • 2
    Including the compiler error number (C26451, I think) and searching for that here on SO will give you several similar questions that should clue you in to the problem. (Which is that the parameter to vector::operator[][ is std::size_t, which is 64 bits.) Commented Jul 18, 2021 at 23:26
  • @1201ProgramAlarm Good observation, Better to use size_t for array indexing and size calculations. Commented Jul 18, 2021 at 23:27

2 Answers 2

1

Vector indexes (and std::vector::size()) are size_ts, not unsigned ints, 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;
        }
    }
}

Live demo

Sign up to request clarification or add additional context in comments.

1 Comment

Oh ok thank you so much, I suspected it had something to do with vector. This actually fixed the error and LeetCode accepted my answer. Thanks again!
1

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, e.g. 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, e.g.

  • 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];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.