Udostępnij za pośrednictwem


Ostrzeżenie C26430

Symbol nie jest testowany pod kątem wartości null we wszystkich ścieżkach.

Podstawowe wytyczne języka C++: F.23: Użyj not_null<T>, aby wskazać, że "null" nie jest prawidłową wartością

Jeśli kod kiedykolwiek sprawdza zmienne wskaźnika dla wartości null, powinien to zrobić spójnie i zweryfikować wskaźniki we wszystkich ścieżkach. Czasami nadmierne sprawdzanie wartości null jest nadal lepsze niż możliwość twardego wypadku w jednej ze skomplikowanych gałęzi. W idealnym przypadku taki kod powinien być refaktoryzowany tak, aby był mniej złożony (przez podzielenie go na wiele funkcji) i polegać na znacznikach, takich jak gsl::not_null. Te znaczniki umożliwiają kodowi izolowanie części algorytmu, które mogą zapewnić bezpieczne założenia dotyczące prawidłowych wartości wskaźnika. Reguła TEST_ON_ALL_PATHS pomaga znaleźć miejsca, w których kontrole null są niespójne (co oznacza, że założenia mogą wymagać przeglądu). Można też znaleźć rzeczywiste usterki, w których potencjalna wartość null może pomijać kontrole wartości null w niektórych ścieżkach kodu.

Uwagi

Ta reguła oczekuje, że kod wyłusza zmienną wskaźnika, tak aby sprawdzanie wartości null (lub wymuszanie wartości innej niż null) było uzasadnione. Jeśli nie ma wyłudzenia, reguła zostanie zawieszona.

Bieżąca implementacja obsługuje tylko zwykłe wskaźniki (lub ich aliasy) i nie wykrywa inteligentnych wskaźników, mimo że kontrole wartości null mają zastosowanie również do inteligentnych wskaźników.

Zmienna jest oznaczona jako zaznaczona pod kątem wartości null, gdy jest używana w następujących kontekstach:

  • jako wyrażenie symbolu w warunku gałęzi, na przykład w if (p) { ... };
  • w nie bitowych operacjach logicznych;
  • w operacjach porównania, w których jeden operand jest wyrażeniem stałym, które daje w wyniku zero.

Reguła nie ma pełnego śledzenia przepływu danych. Może ona generować nieprawidłowe wyniki w przypadkach, gdy są używane kontrole pośrednie (na przykład gdy zmienna pośrednia przechowuje wartość null i jest później używana w porównaniu).

Niejawne kontrole wartości null są zakładane, gdy wartość wskaźnika jest przypisywana z:

  • alokacja wykonywana z rzutowaniem operator new;
  • wskaźnik uzyskany z typu oznaczonego znakiem gsl::not_null.

Przykład

niespójne testowanie ujawnia błąd logiki

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);
    }
}

niespójne testowanie ujawnia błąd logiki — poprawiono

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);
    }
}