Поделиться через


Предупреждение 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