Avertissement C26439
Ce type de fonction peut ne pas lever. Déclarez-le « noexcept ».
C++ Core Guidelines F.6 : Si votre fonction ne doit pas lever, déclarez-la noexcept
Certaines opérations ne doivent jamais lever d’exceptions. Leurs implémentations doivent être fiables et doivent gérer correctement les conditions d’erreurs possibles. Ils ne doivent pas utiliser d’exceptions pour indiquer l’échec. Cette règle signale les cas où ces opérations ne sont pas explicitement marquées comme noexcept
, ce qui signifie qu’elles peuvent lever des exceptions et que les consommateurs ne peuvent pas faire d’hypothèses sur sa fiabilité.
Il est important que ces fonctions soient fiables, car elles sont souvent utilisées comme blocs de construction pour implémenter des fonctions avec des garanties de sécurité d’exception. Un constructeur de déplacement qui lève force les conteneurs STL (Standard Template Library) à revenir aux opérations de copie, ce qui réduit les performances du runtime.
Nom de l’analyse du code : SPECIAL_NOEXCEPT
Notes
Types spéciaux d’opérations :
- Destructeurs;
- constructeurs de déplacement et opérateurs d’affectation de déplacement ;
- fonctions standard avec sémantique de déplacement :
std::move
etstd::swap
.
Les spécificateurs non standard et obsolètes comme
throw()
oudeclspec(nothrow)
ne sont pas équivalents ànoexcept
.Les spécificateurs explicites et
noexcept(true)
sont respectésnoexcept(false)
de manière appropriée.
Exemple
L’outil avertit sur toutes les fonctions, à l’exception du destructeur parce qu’il manque 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'
};
Avec noexcept
la décoration de la même structure, tous les avertissements sont supprimés.
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*/}
};