Я пытался создать пример кода в 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;
по-прежнему выдает предупреждение.
В общем
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);
и все они гарантированно не выходят за пределы.
Это предупреждение о том, что arr[i]
не выполняет проверку границ и что вы должны использовать gsl::at(arr, i)
от https://github.com/Microsoft/GSL вместо этого, поскольку он делает проверку границ и безопаснее.
Я думаю, что причина предупреждения в том, что operator[]
не граничная проверка, пока gsl::at()
мог.
поскольку size
известен во время компиляции, если индекс был constexpr
Вы можете получить предупреждение, но если значение определяется во время выполнения, вы не можете. На мой взгляд довольно ненужный.
Доступ к элементу массива по индексу без какой-либо проверки границ не считается хорошей практикой. Это прямой доступ к памяти, который не является безопасным и может привести к ошибка сегментации.
Для контейнера STL типа std::vector
, есть это at()
функция-член, которая выполняет проверку границ и является рекомендуемым способом доступа к элементам.
Вы можете игнорировать это предупреждение для этого тривиального примера. Но для нетривиального кода используйте std::vector
, Но для массивов в стиле C вы можете скачать и использовать gsl::at()
и изучить его другие объекты, а также.
Рекомендации:
Основные положения C ++
GSL (Руководство по поддержке библиотеки)
Это не предупреждение (компилятор). Это один из Основные положения C ++ включены в сторонний IDE / инструмент анализа.
Это предупреждение как 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;
}