警告 C26429

シンボルは null 値のテストを行うことはなく、次のように gsl::not_nullマークできます。

C++ コア ガイドライン: F.23: "null" が有効な値ではないことを示すために a not_null<T> を使用する

アサートを使用して、ポインター値の有効性に関する前提条件を適用するのが一般的な方法です。 問題は、アサートがインターフェイス (戻り値の型やパラメーターなど) を介して仮定を公開してはいけないという問題です。 アサートは維持が難しく、他のコード変更と常に同期することも困難です。 ガイドライン サポート ライブラリから、 gsl::not_null null 値を指定してはいけないリソースをマークすることをお勧めします。 このルールUSE_NOTNULLは、null のチェックを省略する場所を特定するのに役立ちます。そのため、使用するようにgsl::not_null更新できます。

解説

ルールのロジックでは、null チェック (または null 以外の値の適用) が正当化されるように、ポインター変数を逆参照するコードが必要です。 そのため、警告は、ポインターが逆参照され、null のテストが行われなかった場合にのみ生成されます。

現在の実装では、プレーン ポインター (またはそのエイリアス) のみが処理され、スマート ポインターにも適用できますが、 gsl::not_null スマート ポインターは検出されません。

変数は、次のコンテキストで使用される場合、null に対してチェックとしてマークされます。

  • たとえば、 if (p) { ... }分岐条件のシンボル式として;
  • ビットごとではない論理演算
  • 1 つのオペランドが 0 に評価される定数式である比較演算

ルールには完全なデータフロー追跡がありません。 間接チェックが使用される場合 (中間変数が null 値を保持し、後で比較で使用される場合など) に、不適切な結果が生じる可能性があります。

コード分析名: USE_NOTNULL

隠された期待:

using client_collection = gsl::span<client*>;
// ...
void keep_alive(const connection *connection)   // C26429
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];               // C26429
        client->send_heartbeat();
        // ...
    }
}

隠された期待が明らかに gsl::not_null:

using client_collection = gsl::span<gsl::not_null<client*>>;
// ...
void keep_alive(gsl::not_null<const connection*> connection)
{
    const client_collection clients = connection->get_clients();
    for (ptrdiff_t i = 0; i < clients.size(); i++)
    {
        auto client = clients[i];
        client->send_heartbeat();
        // ...
    }
}