警告 C26431
式 'expr' の型は既に
gsl::not_null
。 null 値をテストしないでください (f.23)
C++ Core Guidelines: 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) { ... }
; - ビットごとではない論理演算
- 1 つのオペランドが 0 に評価される定数式である比較演算
コード分析名: 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;
}
//...