Bagikan melalui


Peringatan C26446

Lebih suka menggunakan gsl::at() alih-alih operator subskrip yang tidak dicentang (bounds.4).

Pedoman Inti C++: Bounds.4: Jangan gunakan fungsi dan jenis pustaka standar yang tidak diperiksa batasnya.

Keterangan

Profil Batas Pedoman Inti C++ mencoba menghilangkan manipulasi memori yang tidak aman. Ini membantu Anda menghindari penggunaan pointer mentah dan operasi yang tidak dicentang. Salah satu cara untuk melakukan akses pemeriksaan rentang seragam ke buffer adalah dengan menggunakan gsl::at() utilitas dari Pustaka Dukungan Pedoman. Ini juga merupakan praktik yang baik untuk mengandalkan implementasi standar yang at() tersedia dalam kontainer STL.

Aturan ini membantu menemukan tempat di mana akses yang berpotensi tidak dicentang dilakukan melalui panggilan ke operator[]. Dalam kebanyakan kasus, Anda dapat mengganti panggilan tersebut dengan menggunakan gsl::at().

  • Akses ke array dengan ukuran yang diketahui ditandai saat indeks non-konstan digunakan dalam operator subskrip. Indeks konstan ditangani oleh C26483 STATIC_INDEX_OUT_OF_RANGE.
  • Logika untuk memperingatkan pada panggilan yang kelebihan operator[] beban lebih kompleks:
    • Jika indeks non-integral, panggilan diabaikan. Ini juga menangani pengindeksan dalam peta standar, karena parameter di operator tersebut diteruskan oleh referensi.
    • Jika operator ditandai sebagai non-throwing (dengan menggunakan noexcept, , throw()atau __declspec(nothrow)), panggilan ditandai. Kami berasumsi bahwa jika operator subskrip tidak pernah melempar pengecualian, operator tersebut tidak melakukan pemeriksaan rentang atau pemeriksaan ini tidak jelas.
    • Jika operator tidak ditandai sebagai non-throwing, operator mungkin ditandai jika berasal dari kontainer STL yang juga mendefinisikan fungsi anggota konvensional at() . Fungsi tersebut terdeteksi dengan pencocokan nama sederhana.
    • Aturan tidak memperingatkan panggilan ke fungsi standar at() . Fungsi-fungsi ini aman; menggantinya dengan gsl::at() tidak akan membawa banyak nilai.
  • Pengindeksan ke dalam std::basic_string_view<> tidak aman, sehingga peringatan dikeluarkan. Ganti standar string_view dengan menggunakan gsl::basic_string_span<>, yang selalu diperiksa terikat.
  • Implementasi tidak mempertimbangkan pemeriksaan rentang yang mungkin memiliki kode pengguna di suatu tempat di perulangan atau cabang. Di sini, akurasi diperdagangkan untuk performa. Secara umum, Anda sering dapat mengganti pemeriksaan rentang eksplisit dengan menggunakan iterator yang lebih andal atau perulangan yang lebih ringkas ditingkatkan for.

Contoh

Contoh ini menunjukkan bagaimana gsl::at fungsi dapat menggantikan referensi terindeks:

// C26446.cpp
#include <vector>
#include <gsl/gsl_util>
#include <iostream>

void fn()
{
    std::vector<int> v{1, 2, 3, 4, 5};
  
    // Normal bracket operators do not prevent you from accessing memory out of bounds.
    std::cout << v[5] << '\n';  // C26446, prefer using gsl::at instead of using operator[].
  
    // gsl::at prevents accessing memory out of bounds and invokes std::terminate on access.
    std::cout << gsl::at(v, 5) << '\n';
}