Avviso C26446
Preferisce usare gsl::at() anziché un operatore di indice non selezionato (bounds.4).
Linee guida di base di C++: Bounds.4: non usare funzioni e tipi di libreria standard che non sono associati.
Osservazioni:
Il profilo Bounds delle linee guida di base di C++ tenta di eliminare le manipolazioni non sicure della memoria. Consente di evitare l'uso di puntatori non elaborati e di operazioni non controllati. Un modo per eseguire l'accesso uniforme controllato dall'intervallo ai buffer consiste nell'usare l'utilità gsl::at()
della libreria di supporto linee guida. È anche consigliabile basarsi sulle implementazioni standard di at()
disponibili nei contenitori STL.
Questa regola consente di individuare le posizioni in cui l'accesso potenzialmente non controllato viene eseguito tramite chiamate a operator[]
. Nella maggior parte dei casi, è possibile sostituire tali chiamate usando gsl::at()
.
- L'accesso alle matrici di dimensioni note viene contrassegnato quando viene usato un indice non costante in un operatore di indice secondario. Gli indici costanti vengono gestiti dal STATIC_INDEX_OUT_OF_RANGE C26483.
- La logica da avvisare sulle chiamate in
operator[]
overload è più complessa:- Se l'indice non è integrale, la chiamata viene ignorata. Questo gestisce anche l'indicizzazione nelle mappe standard, poiché i parametri in tali operatori vengono passati per riferimento.
- Se l'operatore è contrassegnato come non genera un'eccezione (tramite
noexcept
,throw()
o__declspec(nothrow)
), la chiamata viene contrassegnata. Si presuppone che se l'operatore pedice non genera mai eccezioni, non esegue controlli di intervallo o questi controlli sono oscuri. - Se l'operatore non viene contrassegnato come non generato, può essere contrassegnato se proviene da un contenitore STL che definisce anche una funzione membro convenzionale
at()
. Tali funzioni vengono rilevate dalla corrispondenza dei nomi semplice. - La regola non avvisa sulle chiamate alle funzioni standard
at()
. Queste funzioni sono sicure; sostituendoli congsl::at()
non porterebbe molto valore.
- L'indicizzazione in
std::basic_string_view<>
non è sicura, quindi viene generato un avviso. Sostituire lo standardstring_view
usandogsl::basic_string_span<>
, che è sempre associato. - L'implementazione non considera i controlli di intervallo che il codice utente potrebbe includere in cicli o rami. In questo caso, l'accuratezza viene scambiata per le prestazioni. In generale, è spesso possibile sostituire controlli di intervallo espliciti usando iteratori più affidabili o più cicli avanzati concisi
for
.
Esempio
In questo esempio viene illustrato come la gsl::at
funzione può sostituire un riferimento indicizzato:
// 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';
}