Compartir a través de


Advertencia C26446

Se prefiere usar gsl::at() en lugar del operador de subíndice desactivado (bounds.4).

C++ Core Guidelines: Bounds.4: No usar funciones de biblioteca estándar ni tipos en los que no se hayan comprobado los límites.

Comentarios

El perfil Límites de C++ Core Guidelines intenta eliminar las manipulaciones no seguras de memoria. Ayuda a evitar el uso de punteros básicos y operaciones no comprobadas. Una manera de realizar el acceso comprobado de intervalo uniforme a los búferes es usar la utilidad gsl::at() de Guidelines Support Library. También es recomendable confiar en implementaciones estándar de at() disponibles en contenedores STL.

Esta regla ayuda a buscar lugares en los que el acceso potencialmente no comprobado se realiza a través de llamadas a operator[]. En la mayoría de los casos, puede reemplazar estas llamadas mediante gsl::at().

  • El acceso a matrices de tamaño conocido se marca cuando se usa un índice no constante en un operador de subíndice. Los índices constantes se controlan mediante STATIC_INDEX_OUT_OF_RANGE C26483.
  • La lógica para advertir sobre las llamadas sobrecargadas operator[] es más compleja:
    • Si el índice no es integral, se omite la llamada. Esto también controla la indexación en asignaciones estándar, ya que los parámetros de estos operadores se pasan por referencia.
    • Si el operador se marca como que no produce excepciones (mediante noexcept, throw()o __declspec(nothrow)), la llamada se marca. Se supone que si el operador de subíndice nunca produce excepciones, no realiza comprobaciones de intervalo o estas comprobaciones están ocultas.
    • Si el operador no está marcado como que no produce excepciones, se puede marcar si procede de un contenedor STL que también define una función miembro at() convencional. Estas funciones se detectan por simple coincidencia de los nombres.
    • La regla no advierte de las llamadas a funciones estándar at() . Estas funciones son seguras; reemplazarlas por gsl::at() no sería de mucho valor.
  • La indexación en std::basic_string_view<> no es segura, por lo que se emite una advertencia. Reemplace la función string_view estándar mediante gsl::basic_string_span<>, donde siempre se comprueban los límites.
  • La implementación no tiene en cuenta las comprobaciones de intervalo que el código de usuario puede tener en algún lugar en bucles o ramas. Aquí, la precisión se intercambia por rendimiento. En general, a menudo puede reemplazar comprobaciones de intervalos explícitas mediante iteradores más confiables o bucles for mejorados más concisos.

Ejemplo

En este ejemplo se muestra cómo la función gsl::at puede reemplazar una referencia indexada:

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