Арифметическое переполнение с использованием всех 32-битных целых чисел в С++?

Это должно быть просто добавление 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также дал такое же предупреждение, и единственное, что от него избавилось, - это привести все к неподписанному целому числу. Я не понимаю, почему он говорит, что я использую 8-байтовые значения, когда я определенно не использую 8-байтовые значения. Раньше я игнорировал подобные предупреждения, но LeetCode относится к ним очень серьезно. Спасибо.

2 ответа

Векторные индексы (и std::vector::size()) - это s, а не 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;
        }
    }
}

Живая демонстрация

operator[]в определяется как

      constexpr reference operator[]( size_type pos );

плюс несколько подобных перегрузок, все из которых принимают аргумент типа size_typeопределяется . Cppreference.com говорит об этом типе следующее:

Беззнаковый целочисленный тип (обычно std::size_t)

Объяснение о (часть):

std::size_t обычно используется для индексации массива и подсчета циклов. Программы, использующие другие типы, такие как unsigned int, для индексации массива, могут дать сбой, например, в 64-битных системах, когда индекс превышает UINT_MAX или если он основан на 32-битной модульной арифметике.

При индексировании контейнеров 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];
Другие вопросы по тегам