Aracılığıyla paylaş


Uyarı C26430

Sembol tüm yollarda null olup olmadığını test etmemektedir.

C++ Temel Yönergeleri: F.23: "null" değerinin geçerli bir değer olmadığını belirtmek için not_null<T> kullanın

Kod işaretçi değişkenlerini null olarak denetlerse, bunu tutarlı bir şekilde yapmalı ve tüm yollarda işaretçileri doğrulamalıdır. Bazen null için aşırı girişli denetim, karmaşık dallardan birinde sert kilitlenme olasılığından daha iyidir. İdeal olarak, bu tür kod daha az karmaşık olacak şekilde (birden çok işleve bölünerek) ve gibi gsl::not_nullişaretçilere güvenmek için yeniden düzenlenmelidir. Bu işaretçiler, kodun geçerli işaretçi değerleri hakkında güvenli varsayımlarda bulunabilecek algoritma bölümlerini yalıtmasına olanak sağlar. TEST_ON_ALL_PATHS Kural, null denetimlerin tutarsız olduğu yerleri bulmaya yardımcı olur (yani varsayımlar gözden geçirme gerektirebilir). Alternatif olarak, olası bir null değerin bazı kod yollarında null denetimleri atladığı gerçek hataları bulur.

Açıklamalar

Bu kural, null denetimin (veya null olmayan bir değerin zorunlu kılınmasının) iki yana yaslanması için kodun bir işaretçi değişkenine başvurmamasını bekler. Başvuru yoksa kural askıya alınır.

Geçerli uygulama yalnızca düz işaretçileri (veya diğer adlarını) işler ve null denetimler akıllı işaretçiler için de geçerli olsa bile akıllı işaretçileri algılamaz.

Bir değişken, aşağıdaki bağlamlarda kullanıldığında null için işaretlendi olarak işaretlenir:

  • dal koşulunda sembol ifadesi olarak, örneğin, içinde if (p) { ... };
  • bit düzeyinde olmayan mantıksal işlemlerde;
  • karşılaştırma işlemlerinde bir işlenen, sıfır olarak değerlendirilen sabit bir ifadedir.

Aşağıdakilerden bir işaretçi değeri atandığında örtük null denetimleri varsayılır:

  • oluşturma operator newile gerçekleştirilen bir ayırma;
  • ile gsl::not_nullişaretlenmiş bir türden alınan bir işaretçi.

Örnek

tutarsız test, mantıksal hatayı ortaya koyuyor

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

tutarsız test mantıksal hatayı ortaya koyuyor - düzeltildi

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

Buluşsal yöntemler

İşaretçi başvurusunun null olmamasını sağlarken, bu kural her başvurunun önceki null denetimine sahip olmasını gerektirmez. Bunun yerine, işaretçinin ilk başvuruyu kaldırmadan önce null bir denetim gerektirir. Aşağıdaki işlev C26430'yi tetiklemez:

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

Aşağıdaki işlev, null denetim olmadan atanacak *p bir yol olduğundan C26430 oluşturur:

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

C26822 ve C26823 kuralları, (büyük olasılıkla) bir null işaretçinin başvurularını kaldırmaya uygulanır.

Bu kural tam veri akışı izleme yapmaz. Dolaylı denetimlerin kullanıldığı durumlarda, örneğin bir ara değişkenin null değer barındırdığı ve daha sonra karşılaştırmada kullanıldığı durumlarda yanlış sonuçlar verebilir.

Ayrıca bkz.

C26822
C26823