Partager via


Avertissement C26446

Préférez utiliser gsl ::at() au lieu d’un opérateur d’indice non vérifié (bounds.4).

Instructions principales C++ : Bounds.4 : N’utilisez pas de fonctions et de types de bibliothèque standard qui ne sont pas vérifiés par les limites.

Notes

Le profil Bounds des instructions de base C++ tente d’éliminer les manipulations dangereuses de la mémoire. Cela vous permet d’éviter l’utilisation de pointeurs bruts et d’opérations décochées. L’une des façons d’effectuer un accès à la plage uniforme aux mémoires tampons consiste à utiliser l’utilitaire gsl::at() à partir de la bibliothèque de prise en charge des instructions. Il est également recommandé de s’appuyer sur les implémentations standard disponibles at() dans les conteneurs STL.

Cette règle permet de trouver des emplacements où l’accès potentiellement désactivé est effectué via des appels à operator[]. Dans la plupart des cas, vous pouvez remplacer ces appels à l’aide gsl::at()de .

  • L’accès aux tableaux de taille connue est marqué lorsqu’un index non constant est utilisé dans un opérateur d’indice. Les index constants sont gérés par la STATIC_INDEX_OUT_OF_RANGE C26483.
  • La logique à avertir sur les appels surchargés operator[] est plus complexe :
    • Si l’index n’est pas intégral, l’appel est ignoré. Cela gère également l’indexation dans les mappages standard, car les paramètres de ces opérateurs sont passés par référence.
    • Si l’opérateur est marqué comme non levée (à l’aide noexceptde , throw()ou __declspec(nothrow)), l’appel est marqué comme indicateur. Nous partons du principe que si l’opérateur d’indice ne lève jamais d’exceptions, il n’effectue pas de vérifications de plage ou ces vérifications sont obscures.
    • Si l’opérateur n’est pas marqué comme non levée, il peut être marqué s’il provient d’un conteneur STL qui définit également une fonction membre conventionnelle at() . Ces fonctions sont détectées par une correspondance de nom simple.
    • La règle n’avertit pas les appels aux fonctions standard at() . Ces fonctions sont sécurisées ; les gsl::at() remplacer par n’apporterait pas beaucoup de valeur.
  • L’indexation std::basic_string_view<> est non sécurisée. Par conséquent, un avertissement est émis. Remplacez la norme string_view à l’aide gsl::basic_string_span<>de , qui est toujours cochée.
  • L’implémentation ne prend pas en compte les vérifications de plage que le code utilisateur peut avoir quelque part dans des boucles ou des branches. Ici, la précision est échangée pour les performances. En général, vous pouvez souvent remplacer des vérifications de plage explicites à l’aide d’itérateurs plus fiables ou de boucles améliorées forplus concises.

Exemple

Cet exemple montre comment la gsl::at fonction peut remplacer une référence indexée :

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