C26431 DONT_TEST_NOTNULLC26431 DONT_TEST_NOTNULL

"Тип выражения уже GSL:: not_null."The type of expression is already gsl::not_null. Не проверяйте его на допустимость значений NULL».Do not test it for nullness."

C++ Core Guidelines: F. 23: используйте NOT_NULL <T> , чтобы указать, что "null" не является допустимым значением.C++ Core Guidelines: F.23: Use a not_null<T> to indicate that "null" is not a valid value

Тип маркера GSL:: not_null из руководства поддержка библиотеки используется для четкого указания значений, которые никогда не являются пустыми указателями.The marker type gsl::not_null from Guidelines Support Library is used to clearly indicate values that are never null pointers. Это приводит к сбою жесткого сбоя, если такое предположение не удерживается во время выполнения.It causes a hard failure if such assumption is not held at run time. Очевидно, что нет необходимости проверять наличие значений NULL, если результатом выражения является результат типа GSL:: not_null.So, obviously, there is no need to check for nullness if expression evaluates to a result of type gsl::not_null.

КомментарииRemarks

  • Так как GSL:: not_null сам является классом-оболочкой тонкого указателя, правило фактически отслеживает временные переменные, которые содержат результаты вызовов перегруженного оператора преобразования (который возвращает объект указателя).Since gsl::not_null itself is a thin pointer wrapper class, the rule actually tracks temporary variables that hold results from calls to the overloaded conversion operator (which returns contained pointer object). Такая логика делает это правило применимым к выражениям, которые используют переменные и в конечном итоге имеют результат типа GSL:: not_null.Such logic makes this rule applicable to expressions that involve variables and eventually have result of the gsl::not_null type. Но в настоящее время он пропускает выражения, которые содержат вызовы функций, возвращающие GSL:: not_null.But it currently skips expressions that contain function calls returning gsl::not_null.
    • Текущая эвристика для проверок значений NULL обнаруживает следующие контексты:Current heuristic for nullness checks detects the following contexts:
    • Выражение символа в условии ветви, например "if (p) {...}";symbol expression in a branch condition, for example "if (p) { ... }";
    • не побитовые логические операции;non-bitwise logical operations;
    • операции сравнения, в которых один операнд является константным выражением, результатом которого является нуль.comparison operations where one operand is a constant expression that evaluates to zero.

ПримерExample

ненужные проверки NULL раскрывают сомнительную логикуunnecessary null checks reveal questionable logic

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

ненужные проверки NULL раскрывают сомнительную логику — переработаноunnecessary null checks reveal questionable logic - reworked

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