Aviso C26430
O símbolo não é testado quanto à nulidade em todos os caminhos.
Diretrizes principais do C++: F.23: Use um not_null<T> para indicar que "null" não é um valor válido
Se o código verificar variáveis de ponteiro para nulo, ele deve fazê-lo consistentemente e validar ponteiros em todos os caminhos. Às vezes, a verificação excessivamente agressiva de nulo ainda é melhor do que a possibilidade de um travamento rígido em um dos ramos complicados. Idealmente, esse código deve ser refatorado para ser menos complexo (dividindo-o em várias funções) e para confiar em marcadores como gsl::not_null
. Esses marcadores permitem que o código isole partes do algoritmo que podem fazer suposições seguras sobre valores de ponteiro válidos. A regra TEST_ON_ALL_PATHS
ajuda a encontrar locais onde verificações nulas são inconsistentes (o que significa que suposições podem exigir revisão). Ou, ele encontra bugs reais onde um valor nulo potencial pode ignorar verificações nulas em alguns dos caminhos de código.
Comentários
Essa regra espera que o código desreferencia uma variável de ponteiro para que uma verificação nula (ou imposição de um valor não nulo) seja justificada. Se não houver desreferência, a regra é suspensa.
A implementação atual lida apenas com ponteiros simples (ou seus aliases) e não detecta ponteiros inteligentes, embora verificações nulas também sejam aplicáveis a ponteiros inteligentes.
Uma variável é marcada como verificada para nula quando é usada nos seguintes contextos:
- como uma expressão de símbolo em uma condição de ramo, por exemplo, em
if (p) { ... }
; - em operações lógicas não bitwise;
- em operações de comparação em que um operando é uma expressão constante que é avaliada como zero.
A regra não tem controle 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).
Verificações nulas implícitas são assumidas quando um valor de ponteiro é atribuído de:
- uma alocação realizada com arremesso
operator new
; - um ponteiro obtido de um tipo marcado com
gsl::not_null
.
Exemplo
teste inconsistente revela erro lógico
void merge_states(const state *left, const state *right) // C26430
{
if (*left && *right)
converge(left, right);
else
{
// ...
if (!left && !right) // Logic error!
discard(left, right);
}
}
teste inconsistente revela erro lógico – corrigido
void merge_states(gsl::not_null<const state *> left, gsl::not_null<const state *> right)
{
if (*left && *right)
converge(left, right);
else
{
// ...
if (*left && *right)
discard(left, right);
}
}
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de