Condividi tramite


Avviso C26439

Questo tipo di funzione potrebbe non generare. Dichiararlo 'noexcept'.

Linee guida di base di C++F.6: se la funzione non deve generare, dichiararla noexcept

Alcune operazioni non devono mai generare eccezioni. Le implementazioni devono essere affidabili e devono gestire correttamente le possibili condizioni di errore. Non devono usare eccezioni per indicare un errore. Questa regola contrassegna i casi in cui tali operazioni non sono contrassegnate in modo esplicito come noexcept, il che significa che possono generare eccezioni e i consumer non possono fare ipotesi sull'affidabilità.

È importante che queste funzioni siano affidabili perché vengono spesso usate come blocchi predefiniti per implementare funzioni con garanzie di sicurezza delle eccezioni. Un costruttore di spostamento che genera forza il fallback dei contenitori STL (Standard Template Library) alle operazioni di copia, riducendo le prestazioni di runtime.

Nome dell'analisi del codice: SPECIAL_NOEXCEPT

Osservazioni:

  • Tipi speciali di operazioni:

    • Distruttori;
    • spostare costruttori e operatori di assegnazione di spostamento;
    • funzioni standard con semantica di spostamento: std::move e std::swap.
  • Gli identificatori non standard e obsoleti come throw() o declspec(nothrow) non sono equivalenti a noexcept.

  • Gli identificatori espliciti noexcept(false) e noexcept(true) vengono rispettati in modo appropriato.

Esempio

Lo strumento avvisa su tutte le funzioni tranne il distruttore perché mancano noexcept.

struct S
{
    ~S() {}

    S(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)
    S& operator=(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)

    S(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
    S& operator=(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
};

Con noexcept la decorazione della stessa struttura, tutti gli avvisi vengono rimossi.

struct S
{
    ~S() {}

    S(S&& s) noexcept {/*impl*/}
    S& operator=(S&& s) noexcept {/*impl*/}

    S(const S& s) noexcept {/*impl*/}
    S& operator=(const S& s) noexcept {/*impl*/}
};

Vedi anche

C26455
Linee guida di base per C++F.6