Avviso C26448
Prendere in considerazione l'uso
gsl::finally
di se l'azione finale è prevista (gsl.util)
Linee guida di base di C++: GSL.util: Utilità
La libreria di supporto linee guida fornisce un'utilità utile per implementare il concetto di azione finale. Poiché il linguaggio C++ non supporta costrutti try-finally , è diventato comune implementare tipi di pulizia personalizzati che richiamano azioni arbitrarie sulla distruzione. L'utilità gsl::finally
viene implementata in questo modo e offre un modo più uniforme per eseguire azioni finali in una codebase.
Esistono anche casi in cui le azioni finali vengono eseguite in modo C vecchio stile usando goto
istruzioni (sconsigliate da C26438 NO_GOTO). È difficile rilevare l'intenzione esatta nel codice che usa goto
pesantemente , ma alcune euristiche possono aiutare a trovare candidati migliori per la pulizia.
Osservazioni:
- Questa regola è leggera e usa nomi di etichetta per indovinare le opportunità di usare gli oggetti azione finale.
- I nomi di etichetta che possono generare un avviso contengono parole come "end", "final", "clean" e così via.
- Gli avvisi vengono visualizzati nelle
goto
istruzioni . In alcune occasioni è possibile che venga visualizzato un output dettagliato, ma l'output può contribuire a classificare in ordine di priorità il codice, a seconda della complessità. - Questa regola viene sempre associata a C26438 NO_GOTO. A seconda delle priorità, una di queste regole può essere disabilitata.
Nome dell'analisi del codice: USE_GSL_FINALLY
Esempio
Pulizia con più istruzioni goto:
void poll(connection_info info)
{
connection c = {};
if (!c.open(info))
return;
while (c.wait())
{
connection::header h{};
connection::signature s{};
if (!c.read_header(h))
goto end; // C26448 and C26438
if (!c.read_signature(s))
goto end; // C26448 and C26438
// ...
}
end:
c.close();
}
Pulizia con più istruzioni goto sostituite da gsl::finally
:
void poll(connection_info info)
{
connection c = {};
if (!c.open(info))
return;
auto end = gsl::finally([&c] { c.close(); });
while (c.wait())
{
connection::header h{};
connection::signature s{};
if (!c.read_header(h))
return;
if (!c.read_signature(s))
return;
// ...
}
}