Avviso C26414
"Spostare, copiare, riassegnare o reimpostare un puntatore intelligente locale".
Linee guida di base per C++:
R.5: Preferire gli oggetti con ambito, non allocare inutilmente
I puntatori intelligenti sono utili per la gestione dinamica delle risorse, ma non sono sempre necessari. Ad esempio, può essere più semplice ed efficiente gestire un buffer dinamico locale usando un contenitore standard. Potrebbe non essere necessaria l'allocazione dinamica per singoli oggetti, ad esempio se non hanno mai una vita superiore alla funzione creatore. Possono essere sostituiti con variabili locali. I puntatori intelligenti diventano utili quando uno scenario richiede una modifica della proprietà. Ad esempio, quando si riassegna una risorsa dinamica più volte o in più percorsi. Sono utili anche per le risorse ottenute dal codice esterno. Inoltre, quando i puntatori intelligenti vengono usati per estendere la durata di una risorsa.
Osservazioni:
Questo controllo riconosce sia i modelli standard std::unique_pointer
std::shared_pointer
che i tipi definiti dall'utente che sono probabilmente destinati a essere puntatori intelligenti. Tali tipi devono definire le operazioni seguenti:
dereferenziazione o operatori di accesso ai membri di overload pubblici e non contrassegnati come eliminati;
distruttore pubblico non eliminato o predefinito. Che include distruttori definiti in modo esplicito come vuoto.
Il tipo Microsoft::WRL::ComPtr
si comporta come puntatore condiviso, ma viene spesso usato in scenari specifici interessati dalla gestione della durata COM. Per evitare un rumore eccessivo, questo tipo viene filtrato.
Questo controllo cerca le allocazioni locali esplicite assegnate ai puntatori intelligenti per identificare se le variabili con ambito potrebbero funzionare come alternativa. Sia le chiamate dirette all'operatore new
, sia le funzioni speciali come std::make_unique
e std::make_shared
, vengono interpretate come allocazioni dirette.
Nome dell'analisi del codice: RESET_LOCAL_SMART_PTR
Esempio
Buffer dinamico:
void unpack_and_send(const frame &f)
{
auto buffer = std::make_unique<char[]>(f.size()); // C26414
f.unpack(buffer.get());
// ...
}
Buffer dinamico sostituito dal contenitore:
void unpack_and_send(const frame &f)
{
auto buffer = std::vector<char>(f.size());
f.unpack(buffer.data());
// ...
}