Предупреждение C26400
Не присваивайте результат выделения или вызова функции с
owner<T>
возвращаемым значением необработанного указателя, используйтеowner<T>
вместо него (i.11)
Замечания
Эта проверка помогает применить правило *I.11: никогда не передавать владение необработанным указателем (T*), который является подмножеством правила R.3: необработанный указатель (T*) не принадлежит. В частности, он предупреждает о любом вызове operator new
, который сохраняет его результат в переменной необработанного типа указателя. Он также предупреждает о вызовах функций, возвращающих gsl::owner<T>
, если их результаты назначены необработанным указателям. Идея заключается в том, что необходимо четко указать владение ресурсами памяти. Дополнительные сведения см. в основных рекомендациях по C++ .
Самый простой способ исправить это предупреждение — использовать auto
объявление, если ресурс назначается немедленно в объявлении переменной. Если это исправление невозможно, мы рекомендуем использовать тип gsl::owner<T>
. Объявления auto
, инициализированные оператором new
, являются "владельцами", так как мы предполагаем, что результат любого выделения неявно является указателем владельца. Мы переносим это предположение auto
в переменную и рассмотрим ее как owner<T>
.
Если этот флажок помечает вызов функции, возвращаемой owner<T>
, это может быть признаком законной ошибки в коде. В основном это указывает на место, где код утечки явного понятия владения (и, возможно, самого ресурса).
Это правило в настоящее время проверяет только локальные переменные. Если вы назначаете выделение формальному параметру, глобальной переменной, члену класса и т. д., он не помечен. Для будущих работ планируется соответствующее покрытие таких сценариев.
Имя анализа кода: NO_RAW_POINTER_ASSIGNMENT
Пример 1. Простое выделение
char *buffer = nullptr;
if (useCache)
buffer = GetCache();
else
buffer = new char[bufferSize]; // C26400
Пример 2. Простое выделение (исправлено с gsl::owner<T>
)
gsl::owner<char*> buffer = nullptr;
if (useCache)
buffer = GetCache();
else
buffer = new char[bufferSize]; // OK
Пример 3. Простое выделение (исправлено с auto
)
auto buffer = useCache ? GetCache() : new char[bufferSize]; // OK