Bagikan melalui


Peringatan C26449

gsl::span atau std::string_view dibuat dari sementara akan tidak valid ketika sementara tidak valid (gsl.view)

Pedoman Inti C++: GSL.view: Tampilan.

Rentang dan tampilan adalah jenis yang nyaman dan ringan yang memungkinkan Anda mereferensikan buffer memori. Tetapi mereka harus digunakan dengan hati-hati: sementara antarmuka mereka terlihat mirip dengan kontainer standar, perilaku mereka lebih seperti perilaku pointer dan referensi. Mereka tidak memiliki data dan tidak boleh dibangun dari buffer sementara. Pemeriksaan ini berfokus pada kasus di mana data sumber bersifat sementara, sementara rentang atau tampilan tidak. Aturan ini dapat membantu menghindari kesalahan halus tetapi berbahaya yang dilakukan ketika kode warisan dimodernisasi dan mengadopsi rentang atau tampilan. Ada pemeriksaan lain yang menangani skenario yang sedikit berbeda yang melibatkan referensi rentang: C26445 NO_SPAN_REF.

Pertimbangkan untuk menggunakan C26815 dan C26816. Peringatan tersebut adalah versi yang lebih umum dari peringatan ini.

Keterangan

  • Aturan ini memperingatkan tempat di mana konstruktor dipanggil untuk rentang atau tampilan dan buffer data sumber milik objek sementara yang dibuat dalam pernyataan yang sama. Pemeriksaan ini meliputi:

    • konversi implisit dalam pernyataan pengembalian;
    • konversi implisit di operator terner;
    • konversi eksplisit dalam static_cast ekspresi;
    • panggilan fungsi yang mengembalikan kontainer menurut nilai.
  • Sementara yang dibuat untuk argumen panggilan fungsi tidak ditandai. Aman untuk melewati rentang dari sementara tersebut jika fungsi target tidak mempertahankan penunjuk data dalam variabel eksternal.

  • Jika rentang atau tampilan bersifat sementara, aturan akan melewatinya.

  • Pelacakan data di pemeriksa memiliki batasan tertentu; oleh karena itu skenario kompleks yang melibatkan beberapa atau mengaburkan penetapan ulang mungkin tidak ditangani.

Nama analisis kode: NO_SPAN_FROM_TEMPORARY

Contoh

Perbedaan halang dalam jenis hasil:

// 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
        // ...
    }
}

Untuk memperbaiki masalah, pastikan tampilan dibuat dari objek yang hidup setidaknya selama tampilan itu sendiri. Terkadang solusi dapat dicapai dengan menyalin data, di lain waktu beberapa API perlu dirancang ulang untuk berbagi referensi ke objek yang hidup cukup lama alih-alih mengembalikan salinan sementara.

Lihat juga

C26815
C26816