Megosztás:


Figyelmeztetés C26430

A szimbólum nem tesztelt null értéket minden útvonalon.

C++ alapvető irányelvek: F.23: Not_null T> használatával<jelezheti, hogy a "null" nem érvényes érték

Ha a kód valaha null értékre ellenőrzi a mutatóváltozókat, akkor ezt következetesen kell elvégeznie, és minden útvonalon ellenőriznie kell a mutatókat. Néha a null érték túllépése még mindig jobb, mint az egyik bonyolult ág kemény összeomlásának lehetősége. Ideális esetben az ilyen kódokat újra kell bontani, hogy kevésbé összetettek legyenek (több függvényre felosztva), és olyan jelölőkre támaszkodjanak, mint a gsl::not_null. Ezek a jelölők lehetővé teszik, hogy a kód elkülönítse az algoritmus azon részeit, amelyek biztonságos feltételezéseket tehetnek az érvényes mutatóértékekkel kapcsolatban. A szabály TEST_ON_ALL_PATHS segít megtalálni azokat a helyeket, ahol a null ellenőrzések inkonzisztensek (ami azt jelenti, hogy a feltételezések felülvizsgálatot igényelhetnek). Vagy olyan tényleges hibákat talál, amelyekben egy lehetséges null érték megkerülheti a null ellenőrzéseket a kód egyes elérési útjaiban.

Megjegyzések

Ez a szabály arra számít, hogy a kód késleltet egy mutatóváltozót, hogy a null értékű ellenőrzés (vagy a nem null érték érvényesítése) indokolt legyen. Ha nincs halasztás, a szabály fel lesz függesztve.

A jelenlegi implementáció csak egyszerű mutatókat (vagy aliasokat) kezel, és nem észleli az intelligens mutatókat, annak ellenére, hogy a null értékű ellenőrzések az intelligens mutatókra is alkalmazhatók.

A változók akkor vannak bejelölve null értékre, ha a következő környezetekben használják:

  • egy ágfeltétel szimbólumkifejezéseként, például az if (p) { ... };
  • nem bitenkénti logikai műveletekben;
  • összehasonlítási műveletekben, ahol az egyik operandus egy állandó kifejezés, amely nullára értékel.

Implicit nullellenőrzések akkor lesznek feltételezve, ha a mutató értéke a következőhöz van rendelve:

  • dobással operator newvégrehajtott foglalás;
  • egy mutató, amely a jelöléssel ellátott típusból származik gsl::not_null.

példa

inkonzisztens tesztelés logikai hibát tár fel

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

inkonzisztens tesztelés logikai hibát tár fel – kijavítva

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

Heurisztika

Ha biztosítja, hogy egy mutató halasztása ne legyen null értékű, ez a szabály nem követel meg minden halasztást, hogy előzetes nullellenőrzést lehessen végezni. Ehelyett null értékű ellenőrzést igényel a mutató első halasztása előtt. A következő függvény nem aktiválja a C26430-at:

void f(int* p)
{
    if (p)
        *p = 1;
    *p = 2;
}

A következő függvény a C26430-at hozza létre, mert null értékű ellenőrzés nélkül rendelhet hozzá *p elérési utat:

void f(bool b, int* p)
{
    if (b && p)
        *p = 1;
    *p = 2;
}

A C26822 és a C26823 szabályok a (esetleg) null mutató elhalasztására vonatkoznak.

Ez a szabály nem hajtja végre a teljes adatfolyam-nyomkövetést. Helytelen eredményeket eredményezhet olyan esetekben, amikor közvetett ellenőrzéseket használnak, például amikor egy köztes változó null értéket tartalmaz, és később összehasonlításban használják.

Lásd még

C26822
C26823