Compartilhar via


Aviso C26429

O símbolo nunca é testado quanto à nulidade, ele pode ser marcado como gsl::not_null.

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

É uma prática comum usar asserts para impor suposições sobre a validade dos valores de ponteiro. O problema é que as declarações não expõem suposições por meio da interface (como em tipos de retorno ou parâmetros). As asserts também são mais difíceis de manter e manter em sincronia com outras alterações de código. A recomendação é usar gsl::not_null a Biblioteca de Suporte de Diretrizes para marcar recursos que nunca devem ter um valor nulo. A regra USE_NOTNULL ajuda a identificar locais que omitem verificações de nulo e, portanto, podem ser atualizados para usar gsl::not_null.

Comentários

A lógica da regra exige que o código desreferencie uma variável de ponteiro para que uma verificação nula (ou imposição de um valor não nulo) seja justificada. Portanto, os avisos serão emitidos somente se os ponteiros forem desreferenciados e nunca testados quanto a null.

A implementação atual lida apenas com ponteiros simples (ou seus aliases) e não detecta ponteiros inteligentes, embora gsl::not_null também possa ser aplicada a ponteiros inteligentes.

Uma variável é marcada como verificada quanto a nulidade quando é usada nos seguintes contextos:

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

A regra não tem rastreamento completo do fluxo de dados. Ele pode produzir resultados incorretos nos casos em que verificações indiretas são usadas (como quando uma variável intermediária contém um valor nulo e é usada posteriormente em uma comparação).

Nome da análise de código: USE_NOTNULL

Exemplo

Expectativa oculta:

using client_collection = gsl::span<client*>;
// ...
void keep_alive(const connection *connection)   // C26429
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];               // C26429
        client->send_heartbeat();
        // ...
    }
}

Expectativa oculta esclarecida por gsl::not_null:

using client_collection = gsl::span<gsl::not_null<client*>>;
// ...
void keep_alive(gsl::not_null<const connection*> connection)
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];
        client->send_heartbeat();
        // ...
    }
}