Avviso C26400
Non assegnare il risultato di un'allocazione o di una chiamata di funzione con un
owner<T>
valore restituito a un puntatore non elaborato, usareowner<T>
invece (i.11)
Osservazioni:
Questo controllo consente di applicare la *regola I.11: Non trasferire mai la proprietà da un puntatore non elaborato (T*), che è un subset della regola R.3: un puntatore non elaborato (un T*) non è proprietario. In particolare, avvisa su qualsiasi chiamata a operator new
, che salva il risultato in una variabile di tipo puntatore non elaborato. Viene inoltre visualizzato un avviso sulle chiamate alle funzioni che restituiscono gsl::owner<T>
se i risultati vengono assegnati ai puntatori non elaborati. L'idea è che è necessario dichiarare chiaramente la proprietà delle risorse di memoria. Per altre informazioni, vedere Linee guida di base di C++.
Il modo più semplice per correggere questo avviso consiste nell'usare auto
la dichiarazione se la risorsa viene assegnata immediatamente alla dichiarazione della variabile. Se questa correzione non è possibile, è consigliabile usare il tipo gsl::owner<T>
. Le auto
dichiarazioni inizializzate con operatore new
sono "proprietari" perché si presuppone che il risultato di qualsiasi allocazione sia implicitamente un puntatore proprietario. Questo presupposto viene trasferito alla auto
variabile e viene trattato come owner<T>
.
Se questo controllo contrassegna una chiamata a una funzione che restituisce owner<T>
, potrebbe essere un'indicazione di un bug legittimo nel codice. Fondamentalmente, punta a un luogo in cui il codice perde una nozione esplicita di proprietà (e forse la risorsa stessa).
Questa regola controlla attualmente solo le variabili locali. Se si assegna un'allocazione a un parametro formale, a una variabile globale, a un membro di classe e così via, non viene contrassegnata. La copertura appropriata di tali scenari è pianificata per il lavoro futuro.
Nome dell'analisi del codice: NO_RAW_POINTER_ASSIGNMENT
Esempio 1: Allocazione semplice
char *buffer = nullptr;
if (useCache)
buffer = GetCache();
else
buffer = new char[bufferSize]; // C26400
Esempio 2: Allocazione semplice (fissa con gsl::owner<T>
)
gsl::owner<char*> buffer = nullptr;
if (useCache)
buffer = GetCache();
else
buffer = new char[bufferSize]; // OK
Esempio 3: Allocazione semplice (fissa con auto
)
auto buffer = useCache ? GetCache() : new char[bufferSize]; // OK