C26431 DONT_TEST_NOTNULL

"O tipo de expressão já é gsl::not_null. Não teste a nulidade."

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

O tipo de marcador gsl::not_null biblioteca de suporte de diretrizes é usado para indicar claramente valores que nunca são ponteiros nulos. Isso causará uma falha grave se essa suposição não for mantida em tempo de run. Portanto, obviamente, não há necessidade de verificar a nulidade se a expressão for avaliada como um resultado do tipo gsl::not_null.

Comentários

  • Como gsl::not_null em si é uma classe wrapper de ponteiro fino, a regra, na verdade, rastreia variáveis temporárias que retivem resultados de chamadas para o operador de conversão sobrecarregado (que retorna o objeto de ponteiro contido). Essa lógica torna essa regra aplicável a expressões que envolvem variáveis e, eventualmente, têm o resultado do tipo gsl::not_null. No momento, ele ignora expressões que contêm chamadas de função que retornam gsl::not_null.
    • A heurística atual para verificações de nulidade detecta os seguintes contextos:
    • expressão de símbolo em uma condição de branch, por exemplo "if (p) { ... }";
    • operações lógicas não bit a bit;
    • operações de comparação em que um operand é uma expressão constante que é avaliada como zero.

Exemplo

verificações nulas desnecessárias revelam 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 – retrabalho

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