Sdílet prostřednictvím


Upozornění C26431

Typ výrazu výraz 'výraz' je již gsl::not_null. Neotestování hodnoty null (f.23)

C++ Core Guidelines: F.23: Použití not_null<T> k označení, že hodnota null není platná hodnota

Typ gsl::not_null značky z knihovny podpory Pokynů slouží k jasnému označení hodnot, které nikdy nejsou ukazatele null. Pokud se předpoklad v době běhu neudrží, způsobí to těžké selhání. Takže samozřejmě není nutné kontrolovat hodnotu null, pokud se výraz vyhodnotí jako výsledek typu gsl::not_null.

Poznámky

Vzhledem k tomu, že gsl::not_null samotné je obálka s tenkým ukazatelem, pravidlo ve skutečnosti sleduje dočasné proměnné, které obsahují výsledky z volání přetíženého převodního operátoru (který vrací obsažené objekty ukazatele). Tato logika umožňuje toto pravidlo použít pro výrazy, které zahrnují proměnné a nakonec mají výsledek gsl::not_null typu. V současné době však přeskočí výrazy, které obsahují volání funkce vracející gsl::not_null.

Aktuální heuristické pro kontroly null detekuje následující kontexty:

  • výraz symbolu v podmínce větve, například if (p) { ... };
  • nebitové logické operace;
  • operace porovnání, kdy jeden operand je konstantní výraz, který se vyhodnotí na nulu.

Název analýzy kódu: DONT_TEST_NOTNULL

Příklad

Nepotřebné kontroly null odhalí spornou logiku:

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

Nepotřebné kontroly null odhalí spornou logiku a přepracují se:

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