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í
noexcept
throw()
, 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 normustring_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
for
smyč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';
}