Aracılığıyla paylaş


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ı ile gsl::at() değiştirmek çok fazla değer getirmez.
  • dizinini std::basic_string_view<> oluşturmak güvenli olmadığından bir uyarı verilir. Standart string_view değerini, her zaman sınır işaretli olan kullanarak gsl::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';
}