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


Предупреждение C26429

Символ никогда не проверяется на значение NULL, его можно пометить как gsl::not_null.

Основные рекомендации по C++: F.23: используйте значениеnot_null<T>, указывающее, что значение NULL не является допустимым.

Это распространенная практика использования утверждений для принудительного применения предположений о действительности значений указателя. Проблема заключается в том, что утверждения не предоставляют допущения через интерфейс (например, в возвращаемых типах или параметрах). Утверждения также сложнее поддерживать и поддерживать синхронизацию с другими изменениями кода. Рекомендуется использовать gsl::not_null библиотеку поддержки рекомендаций для пометки ресурсов, которые никогда не должны иметь значение NULL. Правило USE_NOTNULL помогает определить места, которые не проверяют значение NULL и поэтому могут быть обновлены для использования gsl::not_null.

Замечания

Логика правила требует от кода разыменовать переменную указателя, чтобы проверка null (или применение значения, отличного от NULL), была оправдана. Таким образом, предупреждения создаются только в том случае, если указатели разыменовываются и никогда не проверяются на значение NULL.

Текущая реализация обрабатывает только простые указатели (или их псевдонимы) и не обнаруживает смарт-указатели, даже если gsl::not_null их можно применить к смарт-указателям.

Переменная помечается как проверяемая значение NULL, если она используется в следующих контекстах:

  • как выражение символа в условии ветви, например; if (p) { ... }
  • небитовые логические операции;
  • операции сравнения, в которых один операнд является константным выражением, которое оценивается как нулевое.

Правило не имеет полного отслеживания потока данных. Он может привести к неправильным результатам в случаях, когда используются косвенные проверки (например, когда промежуточная переменная содержит значение NULL и позже используется в сравнении).

Имя анализа кода: USE_NOTNULL

Пример

Скрытое ожидание:

using client_collection = gsl::span<client*>;
// ...
void keep_alive(const connection *connection)   // C26429
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];               // C26429
        client->send_heartbeat();
        // ...
    }
}

Скрытое ожидание, объясняемое следующим образом gsl::not_null:

using client_collection = gsl::span<gsl::not_null<client*>>;
// ...
void keep_alive(gsl::not_null<const connection*> connection)
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];
        client->send_heartbeat();
        // ...
    }
}