Sdílet prostřednictvím


Upozornění C26446

Raději použijte gsl::at() místo nezaškrtnutého operátoru dolního indexu (bounds.4).

C++ Core Guidelines: Bounds.4: Nepoužívejte funkce a typy standardní knihovny, které nejsou zaškrtnuté.

Poznámky

Profil Bounds v pokynech jazyka C++ Core se snaží odstranit nebezpečné manipulace s pamětí. Pomáhá vyhnout se použití nezpracovaných ukazatelů a nezaškrtnutých operací. Jedním ze způsobů, jak provádět jednotný přístup kontrolovaný rozsah k vyrovnávacím pamětím, je použít gsl::at() nástroj z knihovny podpory pokynů. Osvědčeným postupem je také spoléhat na standardní implementace at() dostupných v kontejnerech STL.

Toto pravidlo pomáhá najít místa, kde se potenciálně nezaškrtnutý přístup provádí prostřednictvím volání operator[]. Ve většině případů můžete taková volání nahradit pomocí .gsl::at()

  • Přístup k polím se známou velikostí označí příznakem, když se v operátoru dolního indexu použije ne constantní index. Konstanty indexy zpracovává STATIC_INDEX_OUT_OF_RANGE C26483.
  • Logika pro upozornění na přetížená operator[] volání je složitější:
    • Pokud index není celočíselný, volání se ignoruje. To také zpracovává indexování ve standardních mapách, protože parametry v takových operátorech jsou předány odkazem.
    • Pokud je operátor označen jako nevyvolaný (pomocí noexceptthrow(), nebo __declspec(nothrow)), volání je označeno příznakem. Předpokládáme, že pokud operátor dolního indexu nikdy nevyvolá výjimky, buď neprovádí kontroly rozsahu, nebo tyto kontroly jsou nejasné.
    • Pokud operátor není označený jako nevyvolaný, může být označen příznakem, pokud pochází z kontejneru STL, který také definuje konvenční členskou at() funkci. Tyto funkce se detekují pomocí jednoduchého párování názvů.
    • Pravidlo varuje při volání standardních at() funkcí. Tyto funkce jsou bezpečné; gsl::at() jejich nahrazení by nepřinesla moc hodnot.
  • Indexování je std::basic_string_view<> nebezpečné, takže se zobrazí upozornění. Nahraďte normu string_view pomocí gsl::basic_string_span<>, která je vždy zaškrtnutá.
  • Implementace nebere v úvahu kontroly rozsahu, které kód uživatele může mít někde ve smyčce nebo větvích. Tady se přesnost obchoduje s výkonem. Obecně platí, že explicitní kontroly rozsahu můžete často nahradit pomocí spolehlivějších iterátorů nebo stručnějších rozšířených forsmyček -.

Příklad

Tento příklad ukazuje, jak gsl::at může funkce nahradit indexovaný odkaz:

// 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';
}