Partager via


Avertissement C26431

Le type d’expression 'expr' est déjà gsl::not_null. Ne testez pas la valeur Nullness (f.23)

C++ Core Guidelines : F.23 : utiliser un <T> not_null pour indiquer que « null » n’est pas une valeur valide

Le type gsl::not_null de marqueur de la bibliothèque de prise en charge des instructions est utilisé pour indiquer clairement les valeurs qui ne sont jamais des pointeurs Null. Cela provoque une défaillance difficile si l’hypothèse ne se tient pas au moment de l’exécution. Donc, évidemment, il n’est pas nécessaire de vérifier la valeur Null si une expression est évaluée à un résultat de type gsl::not_null.

Notes

Étant gsl::not_null donné qu’elle est une classe wrapper de pointeur mince, la règle suit en fait les variables temporaires qui contiennent les résultats des appels à l’opérateur de conversion surchargé (qui retourne des objets pointeurs contenus). Cette logique rend cette règle applicable aux expressions qui impliquent des variables et ont finalement un résultat du gsl::not_null type. Toutefois, il ignore actuellement les expressions qui contiennent des appels de fonction qui retournent gsl::not_null.

L’heuristique actuelle pour les vérifications Null détecte les contextes suivants :

  • une expression de symbole dans une condition de branche, par exemple if (p) { ... };
  • opérations logiques non au niveau du bit ;
  • opérations de comparaison où un opérande est une expression constante qui prend la valeur zéro.

Nom de l’analyse du code : DONT_TEST_NOTNULL

Exemple

Les vérifications null inutiles révèlent une logique interrogeable :

class type {
public:
    template<class T> bool is() const;
    template<class T> gsl::not_null<const T*> as() const;
    //...
};

class alias_type : public type {
public:
    gsl::not_null<const type*> get_underlying_type() const;
    gsl::not_null<const type*> get_root_type() const
    {
        const auto ut = get_underlying_type();
        if (ut)                                     // C26431
        {
            const auto uat = ut->as<alias_type>();
            if (uat)                                // C26431, also incorrect use of API!
                return uat->get_root_type();

            return ut;
        }

        return this;                                // Alias to nothing? Actually, dead code!
    }
    //...
};

Les vérifications null inutiles révèlent une logique discutable, retravaillée :

    //...
    gsl::not_null<const type*> get_root_type() const
    {
        const auto ut = get_underlying_type();
        if (ut->is<alias_type>())
            return ut->as<alias_type>()->get_root_type();

        return ut;
    }
    //...