Не используйте индекс массива, когда индекс не является целочисленным константным выражением; используйте взамен gsl :: at ()

Я пытался создать пример кода в Microsoft Visual Studio, который выглядит так

int main()
{
const size_t size = 10;
int arr[size];

for (size_t i = 0; i < size; ++i)
arr[i] = i;

return 0;
}

Теперь JetBrains ResharperC ++ выдает следующее предупреждение в строке arr[i] = i;

введите описание изображения здесь
Не используйте индекс массива, когда индекс не является целочисленным константным выражением; используйте взамен gsl :: at ()

Я не понимаю, что я имею в виду и как разрешить это предупреждение.

Поскольку эту схему я использовал довольно часто, меня немного беспокоит предупреждение.

Может ли кто-нибудь совет или указать мне в правильном направлении?

РЕДАКТИРОВАТЬ: Изменение цикла на:

for (size_t i = 0; i < size; ++i)
arr[i] = 0;

по-прежнему выдает предупреждение.

5

Решение

В общем

for (size_t i = 0; i < size; ++i)
arr[i] = something;

опасный. Вы не можете сказать, если arr[i] собирается выйти за пределы массива. Вот почему Основные положения C ++ предлагаю вам использовать gsl::at() так как он будет выполнять проверку границ, чтобы убедиться, что вы не выходите за пределы массива.

Это не единственное решение, хотя. Если вам просто нужно выполнить итерацию по диапазону, вы можете использовать диапазон, основанный на цикле, например

for (const auto& e : arr)
//e is each element of the array and is not mutable here

или же

for (auto& e : arr)
//e is each element of the array and is mutable here

И для случая, подобного вашему, где вам нужно заполнить массив, который вы можете использовать std::itoa лайк

std::iota(std::begin(arr), std::end(arr), 0);

и все они гарантированно не выходят за пределы.

2

Другие решения

Это предупреждение о том, что arr[i] не выполняет проверку границ и что вы должны использовать gsl::at(arr, i) от https://github.com/Microsoft/GSL вместо этого, поскольку он делает проверку границ и безопаснее.

4

Я думаю, что причина предупреждения в том, что operator[] не граничная проверка, пока gsl::at() мог.

поскольку size известен во время компиляции, если индекс был constexprВы можете получить предупреждение, но если значение определяется во время выполнения, вы не можете. На мой взгляд довольно ненужный.

2

Доступ к элементу массива по индексу без какой-либо проверки границ не считается хорошей практикой. Это прямой доступ к памяти, который не является безопасным и может привести к ошибка сегментации.

Для контейнера STL типа std::vector, есть это at() функция-член, которая выполняет проверку границ и является рекомендуемым способом доступа к элементам.

Вы можете игнорировать это предупреждение для этого тривиального примера. Но для нетривиального кода используйте std::vector, Но для массивов в стиле C вы можете скачать и использовать gsl::at() и изучить его другие объекты, а также.


Рекомендации:
Основные положения C ++
GSL (Руководство по поддержке библиотеки)

1

Это не предупреждение (компилятор). Это один из Основные положения C ++ включены в сторонний IDE / инструмент анализа.

1

Это предупреждение как operator[] не проверяет связанное, вопреки at,
В то время как в вашем случае код правильный, «маленький» изменение может нарушить ваш цикл (int arr[2 * size];)

В вашем случае есть несколько хороших альтернатив, использующих итераторы (явные или неявные):

const size_t size = 10;
int arr[size];

std::iota(std::begin(arr), std::end(arr), 0);

или же

int i = 0;
for (auto& e : arr) {
e = i;
++i;
}
0
По вопросам рекламы [email protected]