Avertissement C26440

La fonction peut être déclarée « noexcept ».

C++ Core Guidelines F.6 : Si votre fonction peut ne pas lever, déclarez-la noexcept

Si le code n’est censé provoquer aucune exception, il doit être marqué à l’aide du noexcept spécificateur. Cette annotation permet de simplifier la gestion des erreurs côté code client et permet au compilateur d’effectuer davantage d’optimisations.

Notes

  • Une fonction est considérée comme non levée si :
    • elle n’a pas d’instructions explicites throw ;
    • les appels de fonction dans son corps, le cas échéant, appellent uniquement les fonctions qui ne sont pas susceptibles de lever : constexpr ou les fonctions marquées avec une spécification d’exception qui implique un comportement sans levée (y compris certaines spécifications non standard).
  • Les spécificateurs non standard et obsolètes comme throw() ou __declspec(nothrow) ne sont pas équivalents à noexcept.
  • Les spécificateurs explicites et noexcept(true) sont respectés noexcept(false) de manière appropriée.
  • Les fonctions marquées comme constexpr ne sont pas censées provoquer des exceptions et ne sont pas analysées.
  • La règle s’applique également aux expressions lambda.
  • La logique ne considère pas les appels récursifs comme potentiellement non levées. Cette logique peut changer à l’avenir.

Exemple

Toutes les fonctions, à l’exception du destructeur, avertiront parce qu’elles ne manquent pas d’exception.

struct S
{
    S() {} // C26455, Default constructor may not throw. Declare it 'noexcept'
    ~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'
};

Avec noexcept décorant la même structure, tous les avertissements sont supprimés.

struct S
{
    S() noexcept {}
    ~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*/}
};