Search code examples
c++arithmetic-overflow

Arithmetic overflow using all 32-bit ints in C++?


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.


Solution

  • 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