Condividi tramite


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, usare owner<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