警告 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;
}
//...