Condividi tramite


Avviso C26431

Il tipo di espressione 'expr' è già gsl::not_null. Non testarla per verificare la nullità (f.23)

Linee guida di base di C++: F.23: Usare un not_null<T> per indicare che "null" non è un valore valido

Il tipo di gsl::not_null marcatore della libreria di supporto linee guida viene usato per indicare chiaramente i valori che non sono mai puntatori Null. Si verifica un errore difficile se il presupposto non è in esecuzione. Pertanto, ovviamente, non è necessario verificare se un'espressione restituisce un risultato di tipo gsl::not_null.

Osservazioni:

Poiché gsl::not_null si tratta di una classe wrapper puntatore sottile, la regola tiene effettivamente traccia delle variabili temporanee che contengono i risultati dalle chiamate all'operatore di conversione di overload (che restituisce oggetti puntatore contenuti). Tale logica rende questa regola applicabile alle espressioni che coinvolgono variabili e alla fine hanno un risultato del gsl::not_null tipo. Tuttavia, attualmente ignora le espressioni che contengono chiamate di funzione che gsl::not_nullrestituiscono .

L'euristica corrente per i controlli Null rileva i contesti seguenti:

  • un'espressione di simbolo in una condizione di ramo, ad esempio if (p) { ... };
  • operazioni logiche non bit per bit;
  • operazioni di confronto in cui un operando è un'espressione costante che restituisce zero.

Nome dell'analisi del codice: DONT_TEST_NOTNULL

Esempio

I controlli Null non necessari rivelano la logica discutibile:

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

I controlli Null non necessari rivelano logica discutibile, rielaborata:

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