共用方式為


警告 C26430

未在所有路徑上測試符號是否為 Null。

C++ Core GuidelinesF.23:使用 not_null<T> 表示“null” 不是有效值

如果程式碼曾經檢查指標變數是否為 Null 值,則應該一致地執行,並驗證所有路徑上的指標。 有時候,寧可過度執行 Null 檢查,也不要有其中一個複雜分支發生封鎖性損毀的可能性。 在理想情況下,應重構這類程式碼使其較不複雜 (透過將其分割成多個函式),並依賴 gsl::not_null 之類的標記。 這些標記可讓程式碼隔離演算法的各部分,以安全地假設指標值有效。 TEST_ON_ALL_PATHS 規則有助於尋找 Null 檢查不一致的地方 (這表示可能需要檢閱假設)。 或者,它會尋找潛在 Null 值可能在某些程式碼路徑中略過 Null 檢查的實際 Bug。

備註

此規則預期程式碼會對指標變數進行取值 (Dereference),以正當化 Null 檢查 (或強制執行非 Null 值)。 如果沒有取值,則會暫停規則。

目前的實作只會處理簡單的指標 (或其別名),不會偵測智慧指標,但 Null 檢查也適用於智慧指標。

當變數用於下列內容時,會標示為檢查是否為 Null:

  • 作為分支條件中的符號運算式,例如在 if (p) { ... } 中;
  • 在非位元邏輯運算中;
  • 在比較運算中,其中一個運算元是評估為零的常數運算式。

透過下列方式指派指標值時,會假設隱含 Null 檢查:

  • 執行後擲回 operator new 的配置;
  • 從標示為 gsl::not_null 的類型取得的指標。

範例

不一致的測試顯示邏輯錯誤

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

不一致的測試顯示邏輯錯誤 - 已更正

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

啟發學習法

確保指標的取值不是 Null 時,此規則不需要「每個」取值都要事先進行 Null 檢查。 相反地,它需要在指標的「第一個」取值之前進行 Null 檢查。 下列函式不會觸發 C26430:

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

下列函式會產生 C26430,因為有一個指派 *p 的路徑未進行 Null 檢查:

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

C26822C26823 規則適用於取值的指標 (可能) 為 Null 的情況。

此規則不會執行完整的資料流程追蹤。 在使用間接檢查的情況下 (例如當中繼變數包含 Null 值並在稍後用於比較時),可能會產生不正確的結果。

另請參閱

C26822
C26823