Предупреждение 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();
// ...
}
}