Warnung C26429
Symbol wird niemals auf Nullwerte getestet, es kann als
gsl::not_null
gekennzeichnet werden.
C++-Kernrichtlinien: F.23: Verwenden Sie eine not_null<T>
, um anzugeben, dass "null" kein gültiger Wert ist.
Es ist eine gängige Methode, Assertionen zu verwenden, um Annahmen über die Gültigkeit von Zeigerwerten zu erzwingen. Das Problem besteht darin, dass behauptet wird, keine Annahmen über die Schnittstelle (z. B. in Rückgabetypen oder Parametern) verfügbar zu machen. Assertionen sind auch schwieriger zu Standard und mit anderen Codeänderungen synchron zu halten. Die Empfehlung besteht darin, aus der Richtlinienunterstützungsbibliothek zu verwenden gsl::not_null
, um Ressourcen zu markieren, die niemals einen NULL-Wert aufweisen sollten. Die Regel USE_NOTNULL
hilft dabei, Orte zu identifizieren, die keine Überprüfungen auf NULL auslassen, und daher zur Verwendung gsl::not_null
aktualisiert werden können.
Hinweise
Für die Logik der Regel ist code erforderlich, um eine Zeigervariable abzuleiten, sodass eine NULL-Prüfung (oder Erzwingung eines Nicht-Null-Werts) gerechtfertigt wäre. Warnungen werden also nur ausgegeben, wenn Zeiger abgeleitet und nie auf NULL getestet werden.
Die aktuelle Implementierung behandelt nur einfache Zeiger (oder ihre Aliase) und erkennt keine intelligenten Zeiger, auch wenn gsl::not_null
sie auch auf intelligente Zeiger angewendet werden können.
Eine Variable wird als "null" markiert, wenn sie in den folgenden Kontexten verwendet wird:
- als Symbolausdruck in einer Verzweigungsbedingung,
if (p) { ... }
z. B. ; - nicht bitweise logische Vorgänge;
- Vergleichsvorgänge, bei denen ein Operand ein konstanter Ausdruck ist, der als Null ausgewertet wird.
Die Regel hat keine vollständige Datenflussnachverfolgung. Es kann zu falschen Ergebnissen führen, wenn indirekte Prüfungen verwendet werden (z. B. wenn eine Zwischenvariable einen NULL-Wert enthält und später in einem Vergleich verwendet wird).
Codeanalysename: USE_NOTNULL
Beispiel
Ausgeblendete Erwartung:
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();
// ...
}
}
Ausgeblendete Erwartung geklärt durch 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();
// ...
}
}