Avviso C26429
Il simbolo non viene mai testato per verificare la nullità, ma può essere contrassegnato come
gsl::not_null
.
Linee guida di base di C++: F.23: usare un not_null<T>
per indicare che "null" non è un valore valido
È una pratica comune usare asserzioni per imporre presupposti sulla validità dei valori del puntatore. Il problema è che le asserzioni non espongono presupposti tramite l'interfaccia , ad esempio nei tipi restituiti o nei parametri. Le asserzioni sono anche più difficili da gestire e mantenere sincronizzate con altre modifiche al codice. È consigliabile usare gsl::not_null
la libreria di supporto linee guida per contrassegnare le risorse che non devono mai avere un valore Null. La regola USE_NOTNULL
consente di identificare le posizioni che omettono i controlli per i valori Null e di conseguenza possono essere aggiornate per l'uso di gsl::not_null
.
Osservazioni:
La logica della regola richiede che il codice dereferenzii una variabile puntatore in modo che venga giustificato un controllo Null (o l'imposizione di un valore non Null). Gli avvisi vengono quindi generati solo se i puntatori vengono dereferenziati e non vengono mai testati per i valori Null.
L'implementazione corrente gestisce solo puntatori semplici (o i relativi alias) e non rileva puntatori intelligenti, anche se gsl::not_null
può essere applicato anche ai puntatori intelligenti.
Una variabile viene contrassegnata come selezionata per i valori Null quando viene usata nei contesti seguenti:
- come espressione di simbolo in una condizione di ramo, ad esempio ;
if (p) { ... }
- operazioni logiche non bit per bit;
- operazioni di confronto in cui un operando è un'espressione costante che restituisce zero.
La regola non dispone del rilevamento completo del flusso di dati. Può produrre risultati non corretti nei casi in cui vengono usati controlli indiretti, ad esempio quando una variabile intermedia contiene un valore Null e viene usata successivamente in un confronto.
Nome dell'analisi del codice: USE_NOTNULL
Esempio
Aspettative nascoste:
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();
// ...
}
}
Aspettative nascoste chiarite da 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();
// ...
}
}