Udostępnij za pośrednictwem


Ostrzeżenie C26431

Typ wyrażenia "wyrażenie" ma już wartość gsl::not_null. Nie testuj go pod kątem wartości null (f.23)

Podstawowe wytyczne języka C++: F.23: Użyj not_null<T>, aby wskazać, że "null" nie jest prawidłową wartością

Typ gsl::not_null znacznika z biblioteki pomocy technicznej wytycznych służy do wyraźnego wskazywania wartości, które nigdy nie mają wartości null. Powoduje to trudną awarię, jeśli założenie nie jest przechowywane w czasie wykonywania. Dlatego oczywiście nie ma potrzeby sprawdzania wartości null, jeśli wyrażenie daje wynik typu gsl::not_null.

Uwagi

Ponieważ gsl::not_null sama jest klasą otoki cienkiego wskaźnika, reguła faktycznie śledzi zmienne tymczasowe, które przechowują wyniki z wywołań do przeciążonego operatora konwersji (który zwraca zawarte obiekty wskaźnika). Taka logika sprawia, że ta reguła ma zastosowanie do wyrażeń, które obejmują zmienne i ostatecznie mają wynik gsl::not_null typu. Obecnie pomija ona jednak wyrażenia zawierające wywołania funkcji zwracające gsl::not_nullwartość .

Bieżąca heurystyka sprawdzania wartości null wykrywa następujące konteksty:

  • wyrażenie symbolu w warunku gałęzi, na przykład if (p) { ... };
  • nie bitowe operacje logiczne;
  • operacje porównania, w których jeden operand jest wyrażeniem stałym, które daje w wyniku zero.

Nazwa analizy kodu: DONT_TEST_NOTNULL

Przykład

Niepotrzebne kontrole wartości null ujawniają wątpliwą logikę:

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

Niepotrzebne kontrole wartości null ujawniają wątpliwą logikę, przerobione:

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