Предупреждение C26446
Предпочитайте использовать gsl::at() вместо снятого оператора подстрока (bounds.4).
Основные рекомендации по C++ : Bounds.4. Не используйте функции и типы стандартной библиотеки, которые не проверяются.
Замечания
Профиль Bounds основного руководства C++ пытается устранить небезопасные манипуляции с памятью. Это помогает избежать использования необработанных указателей и снятых операций. Одним из способов обеспечения единообразного доступа к буферам является использование gsl::at()
служебной программы из библиотеки поддержки рекомендаций. Кроме того, рекомендуется использовать стандартные реализации, доступные в контейнерах at()
STL.
Это правило помогает найти места, где потенциально снятый доступ выполняется с помощью вызовов operator[]
. В большинстве случаев такие вызовы можно заменить с помощью gsl::at()
.
- Доступ к массивам известного размера помечается при использовании неконстантного индекса в операторе подстрока. Константные индексы обрабатываются STATIC_INDEX_OUT_OF_RANGE C26483.
- Логика предупреждения о перегруженных
operator[]
вызовах является более сложной:- Если индекс не является целочисленным, вызов игнорируется. Это также обрабатывает индексирование в стандартных картах, так как параметры в таких операторах передаются по ссылке.
- Если оператор помечается как неисключаемый (с помощью
noexcept
throw()
или__declspec(nothrow)
), вызов помечается. Предположим, что если оператор подстрока никогда не создает исключения, он либо не выполняет проверки диапазона, либо эти проверки не являются неясными. - Если оператор не помечается как неисполнение, он может быть помечен, если он поступает из контейнера STL, который также определяет обычную
at()
функцию-член. Такие функции обнаруживаются простым сопоставлением имен. - Правило не предупреждает о вызовах стандартных
at()
функций. Эти функции безопасны; замена ихgsl::at()
не принесет большого значения.
- Индексирование
std::basic_string_view<>
в небезопасное, поэтому выдается предупреждение. Замените стандартstring_view
с помощьюgsl::basic_string_span<>
функции , которая всегда проверяет границы. - Реализация не считает, что код пользователя может быть где-то в циклах или ветвях. Здесь точность торгуется на производительность. Как правило, часто можно заменить явные проверки диапазона с помощью более надежных итераторов или более кратких расширенных
for
циклов ..
Пример
В этом примере показано, как gsl::at
функция может заменить индексированную ссылку:
// C26446.cpp
#include <vector>
#include <gsl/gsl_util>
#include <iostream>
void fn()
{
std::vector<int> v{1, 2, 3, 4, 5};
// Normal bracket operators do not prevent you from accessing memory out of bounds.
std::cout << v[5] << '\n'; // C26446, prefer using gsl::at instead of using operator[].
// gsl::at prevents accessing memory out of bounds and invokes std::terminate on access.
std::cout << gsl::at(v, 5) << '\n';
}