分享方式:


警告 C26431

運算式 ' expr ' 的類型已經 gsl::not_null 是 。 請勿測試它是否為 Null (f.23)

C++ 核心指導方針 :F.23 使用 not_null < T > 表示 「null」 不是有效的值

來自指導方針支援程式庫的標記類型 gsl::not_null 可用來清楚指出絕不為 Null 指標的值。 如果假設在執行時間未保留,就會造成硬性失敗。 因此,很明顯,如果運算式評估為 類型的 gsl::not_null 結果,就不需要檢查 null。

備註

由於 gsl::not_null 本身是精簡指標包裝函式類別,因此規則實際上會追蹤暫存變數,這些變數會保留呼叫多載轉換運算子的結果(這會傳回包含的指標物件)。 這類邏輯可讓此規則適用于牽涉變數的運算式,且最終會有 型別 gsl::not_null 的結果。 不過,它目前會略過包含傳回 之函式呼叫的 gsl::not_null 運算式。

目前 Null 檢查的啟發學習法會偵測到下列內容:

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

程式碼分析名稱: DONT_TEST_NOTNULL

範例

不必要的 Null 檢查會顯示可疑的邏輯:

class type {
public:
    template<class T> bool is() const;
    template<class T> gsl::not_null<const T*> as() const;
    //...
};

class alias_type : public type {
public:
    gsl::not_null<const type*> get_underlying_type() const;
    gsl::not_null<const type*> get_root_type() const
    {
        const auto ut = get_underlying_type();
        if (ut)                                     // C26431
        {
            const auto uat = ut->as<alias_type>();
            if (uat)                                // C26431, also incorrect use of API!
                return uat->get_root_type();

            return ut;
        }

        return this;                                // Alias to nothing? Actually, dead code!
    }
    //...
};

不必要的 Null 檢查會顯示可疑的邏輯,並重新作業:

    //...
    gsl::not_null<const type*> get_root_type() const
    {
        const auto ut = get_underlying_type();
        if (ut->is<alias_type>())
            return ut->as<alias_type>()->get_root_type();

        return ut;
    }
    //...