Sdílet prostřednictvím


Upozornění C26429

Symbol není nikdy testován na hodnotu null, může být označen jako gsl::not_null.

C++ Core Guidelines: F.23: Použijte not_null<T> k označení, že hodnota null není platná hodnota.

Běžným postupem je použití kontrolních výrazů k vynucení předpokladů o platnosti hodnot ukazatele. Problémem je, že kontrolní výrazy nezpřístupňují předpoklady prostřednictvím rozhraní (například v návratových typech nebo parametrech). Kontrolní výrazy jsou také obtížnější udržovat a synchronizovat s jinými změnami kódu. Doporučujeme použít gsl::not_null knihovnu podpory pokynů k označení prostředků, které by nikdy neměly mít hodnotu null. Toto pravidlo USE_NOTNULL pomáhá identifikovat místa, kde vynecháte kontroly hodnoty null, a proto je možné je aktualizovat tak, aby používala gsl::not_null.

Poznámky

Logika pravidla vyžaduje, aby kód odvozoval proměnnou ukazatele tak, aby byla zadůvodněná kontrola null (nebo vynucení hodnoty, která není null). Upozornění se proto vygenerují pouze v případě, že jsou ukazatele dereferenced a nikdy se neotestovaly na hodnotu null.

Aktuální implementace zpracovává pouze prosté ukazatele (nebo jejich aliasy) a nerozpozná inteligentní ukazatele, i když gsl::not_null je možné je použít i u inteligentních ukazatelů.

Proměnná se označí jako zaškrtnutá, pokud se použije v následujících kontextech:

  • jako výraz symbolu v podmínce větve, if (p) { ... }například ;
  • nebitové logické operace;
  • operace porovnání, kdy jeden operand je konstantní výraz, který se vyhodnotí na nulu.

Pravidlo nemá úplné sledování toku dat. Může vést k nesprávným výsledkům v případech, kdy se používají nepřímé kontroly (například když zprostředkující proměnná obsahuje hodnotu null a později se použije v porovnání).

Název analýzy kódu: USE_NOTNULL

Příklad

Skryté očekávání:

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

Skryté očekávání objasněné 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();
        // ...
    }
}