次の方法で共有


警告 C26429

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

C++ コア ガイドライン: F.23: not_null<T> を使用して、"null" が有効な値ではないことを示します

アサートを使用して、ポインター値の有効性に関する前提条件を適用するのが一般的な方法です。 問題は、アサートがインターフェイス (戻り値の型やパラメーターなど) を介して仮定を公開してはいけないという問題です。 アサートは維持が難しく、他のコード変更と常に同期することも困難です。 ガイドライン サポート ライブラリの 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();
        // ...
    }
}