共用方式為


警告 C26449

gsl::spanstd::string_view 從暫時建立的 ,在暫時失效時會無效 (gsl.view)

C++ 核心指導方針: GSL.view:檢視

範圍和檢視是方便且輕量型別,可讓您參考記憶體緩衝區。 但必須仔細使用它們:雖然其介面看起來類似于標準容器,但其行為更像是指標和參考的行為。 它們不擁有資料,而且絕不能從暫存緩衝區建構。 此檢查著重于來源資料是暫時性的案例,而範圍或檢視則不是。 此規則有助於避免在舊版程式碼現代化並採用範圍或檢視時所犯的微妙但危險的錯誤。 另一個檢查會處理涉及範圍參考的略有不同的案例: C26445 NO_SPAN_REF

請考慮使用 C26815 C26816 。 這些警告是此警告的較一般版本。

備註

  • 此規則會在針對範圍或檢視叫用建構函式的位置發出警告,而源資料緩衝區屬於在相同語句中建立的暫存物件。 這項檢查包括:

    • 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