Condividi tramite


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 gotopesantemente , 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;
        // ...
    }
}