Uyarı C26446
İşaretlenmemiş alt simge işleci (bounds.4) yerine gsl::at() kullanmayı tercih edin.
C++ Temel Yönergeleri: Sınırlar.4: Sınır denetimi yapılmayan standart kitaplık işlevlerini ve türlerini kullanmayın.
Açıklamalar
C++ Çekirdek Yönergelerinin Sınır profili, belleğin güvenli olmayan işlemelerini ortadan kaldırmaya çalışır. Ham işaretçilerin ve işaretsiz işlemlerin kullanılmasını önlemenize yardımcı olur. Arabelleklere tekdüzen aralık denetimi erişimi gerçekleştirmenin gsl::at()
bir yolu, Yönergeler Destek Kitaplığı'ndan yardımcı programını kullanmaktır. STL kapsayıcılarında kullanılabilen standart uygulamalarına at()
güvenmek de iyi bir uygulamadır.
Bu kural, aramalar aracılığıyla operator[]
denetlenmemiş olabilecek erişimin gerçekleştirildiği yerleri bulmaya yardımcı olur. Çoğu durumda, kullanarak gsl::at()
bu tür çağrıları değiştirebilirsiniz.
- Bir alt simge işlecinde sabit olmayan bir dizin kullanıldığında, bilinen boyuttaki dizilere erişim bayrakla işaretlenir. Sabit dizinler C26483 STATIC_INDEX_OUT_OF_RANGE tarafından işlenir.
- Aşırı yüklenmiş
operator[]
çağrılarda uyarıda bulunan mantık daha karmaşıktır:- Dizin tam sayı değilse çağrı yoksayılır. Bu, standart eşlemelerde dizin oluşturmayı da işler, çünkü bu tür işleçlerdeki parametreler başvuruyla geçirilir.
- İşleç atanmayan olarak işaretlenmişse (,
throw()
veya__declspec(nothrow)
kullanılaraknoexcept
), çağrı işaretlenir. Alt simge işleci hiçbir zaman özel durum oluşturmazsa, aralık denetimleri gerçekleştirmediğini veya bu denetimlerin belirsiz olduğunu varsayarız. - İşleç atılmayan olarak işaretlenmemişse, geleneksel
at()
üye işlevini de tanımlayan bir STL kapsayıcısından geliyorsa işaretlenebilir. Bu tür işlevler basit ad eşleştirme ile algılandı. - Kural, standart
at()
işlevlere yapılan çağrılarda uyarı vermez. Bu işlevler güvenlidir; bunları ilegsl::at()
değiştirmek çok fazla değer getirmez.
- dizinini
std::basic_string_view<>
oluşturmak güvenli olmadığından bir uyarı verilir. Standartstring_view
değerini, her zaman sınır işaretli olan kullanarakgsl::basic_string_span<>
değiştirin. - Uygulama, kullanıcı kodunun döngülerde veya dallarda bir yerde bulunabileceği aralık denetimlerini dikkate almaz. Burada doğruluk, performansla takas edilir. Genel olarak, genellikle daha güvenilir yineleyiciler veya daha kısa gelişmiş
for
-döngüler kullanarak açık aralık denetimlerini değiştirebilirsiniz.
Örnek
Bu örnekte işlevin dizine alınan başvurunun gsl::at
yerini nasıl değiştirebileceği gösterilmektedir:
// 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';
}