Share via


警告 C26449

gsl::span または std::string_view 一時から作成された場合、一時が無効になると無効になります (gsl.view)

C++ Core Guidelines: GSL.view: Views.

スパンとビューは、メモリ バッファーを参照できる便利で軽量な型です。 ただし、これらは慎重に使用する必要があります。インターフェイスは標準のコンテナーに似ていますが、その動作はポインターと参照の動作に似ています。 これらはデータを所有せず、一時バッファーから構築してはなりません。 このチェックでは、スパンまたはビューが一時的ではない場合に、ソース データが一時的なケースに焦点を当てています。 このルールは、レガシ コードが最新化され、スパンまたはビューを採用するときに発生する微妙で危険な間違いを回避するのに役立ちます。 スパン参照を含む少し異なるシナリオを処理する別のチェックがあります:C26445 NO_SPAN_REF

C26815C26816 の使用を検討してください。 これらの警告は、この警告のより一般的なバージョンです。

解説

  • このルールは、コンストラクターがスパンまたはビューに対して呼び出され、ソース データ バッファーが同じステートメントで作成された一時オブジェクトに属している場所で警告します。 このチェックには次のものが含まれます。

    • return ステートメントの暗黙的な変換。
    • 三項演算子の暗黙的な変換。
    • static_cast 式の明示的な変換。
    • 値によってコンテナーを返す関数呼び出し。
  • 関数呼び出し引数に対して作成された一時的なフラグは設定されません。 ターゲット関数が外部変数にデータ ポインターを保持しない場合は、このような一時的な部分からスパンを渡しても安全です。

  • スパンまたはビュー自体が一時要素の場合は、ルールによってスキップされます。

  • チェッカーでのデータ追跡には、特定の制限があります。したがって、複数の再割り当てやあいまいな再割り当てを伴う複雑なシナリオは処理されない可能性があります。

コード分析名: NO_SPAN_FROM_TEMPORARY

結果の種類の微妙な違い:

// Returns a predefined collection. Keeps data alive.
gsl::span<const sequence_item> get_seed_sequence() noexcept;

// Returns a generated collection. Doesn't own new data.
std::vector<sequence_item> get_next_sequence(gsl::span<const sequence_item>);

void run_batch()
{
    auto sequence = get_seed_sequence();
    while (send(sequence))
    {
        sequence = get_next_sequence(sequence); // C26449
        // ...
    }
}

この問題を解決するには、少なくともビュー自体が存在するオブジェクトからビューが作成されていることを確認します。 場合によっては、データをコピーすることでソリューションを実現できる場合もあれば、一時的なコピーを返すのではなく、十分な長さのオブジェクトへの参照を共有するために一部の API を再設計する必要がある場合もあります。

関連項目

C26815
C26816