Condividi tramite


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 con gsl::at() non porterebbe molto valore.
  • L'indicizzazione in std::basic_string_view<> non è sicura, quindi viene generato un avviso. Sostituire lo standard string_view usando gsl::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';
}