Поделиться через


Предупреждение C26431

Тип выражения expr уже gsl::not_null. Не проверяйте его на наличие значений NULL (f.23)

Основные рекомендации по C++ : F.23: используйте not_null<T>, чтобы указать, что значение NULL не является допустимым значением

Тип gsl::not_null маркера из библиотеки поддержки рекомендаций используется для четкого указания значений, которые никогда не являются пустыми указателями. Это приводит к жесткому сбою, если предположение не содержится во время выполнения. Таким образом, очевидно, нет необходимости проверять значение NULL, если выражение вычисляется в результате типа gsl::not_null.

Замечания

Так как gsl::not_null сам по себе является классом оболочки с тонким указателем, правило фактически отслеживает временные переменные, содержащие результаты из вызовов перегруженного оператора преобразования (который возвращает содержащиеся объекты указателя). Такая логика делает это правило применимым к выражениям, которые включают переменные и в конечном итоге имеют результат gsl::not_null типа. Однако в настоящее время он пропускает выражения, содержащие возвращаемые gsl::not_nullвызовы функций.

Текущая эвристика для проверок null определяет следующие контексты:

  • выражение символа в условии ветви, например if (p) { ... };
  • небитовые логические операции;
  • операции сравнения, в которых один операнд является константным выражением, которое оценивается как нулевое.

Имя анализа кода: DONT_TEST_NOTNULL

Пример

Ненужные проверки NULL показывают сомнительных логику:

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 показывают сомнительные логики, переработаны:

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