Share via


警告 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) { ... }分岐条件のシンボル式。
  • ビットごとではない論理演算
  • 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;
    }
    //...