Partilhar via


Aviso C26431

O tipo de expressão 'expr' já gsl::not_nullé . Não testar a nulidade (f.23)

Diretrizes principais do C++: F.23: Use um not_null<T> para indicar que "null" não é um valor válido

O tipo gsl::not_null de marcador da Biblioteca de Suporte de Diretrizes é usado para indicar claramente valores que nunca são ponteiros nulos. Isso causa uma falha difícil se a suposição não for mantida em tempo de execução. Então, obviamente, não há necessidade de verificar se uma expressão é avaliada como um resultado do tipo gsl::not_null.

Observações

Como gsl::not_null ela própria é uma classe de wrapper de ponteiro fino, a regra realmente rastreia variáveis temporárias que armazenam resultados de chamadas para o operador de conversão sobrecarregado (que retorna objetos de ponteiro contidos). Tal lógica torna esta regra aplicável a expressões que envolvem variáveis e eventualmente têm um resultado do gsl::not_null tipo. No entanto, ele atualmente ignora expressões que contêm chamadas de função retornando gsl::not_null.

A heurística atual para verificações nulas deteta os seguintes contextos:

  • uma expressão de símbolo em uma condição de ramo, por exemplo if (p) { ... };
  • operações lógicas não bitwise;
  • operações de comparação em que um operando é uma expressão constante que é avaliada como zero.

Nome da análise de código: DONT_TEST_NOTNULL

Exemplo

Verificações nulas desnecessárias revelam uma lógica questionável:

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

Verificações nulas desnecessárias revelam lógica questionável, retrabalhada:

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