Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Prefira usar gsl::at() em vez do operador subscrito não verificado (bounds.4).
Diretrizes Principais do C++: Bounds.4: Não use funções da biblioteca padrão nem tipos que não tem limites verificados.
Comentários
O perfil Bounds das Diretrizes principais do C++ tenta eliminar manipulações não seguras de memória. Ele ajuda a evitar o uso de ponteiros brutos e operações não verificadas. Uma forma de executar o acesso uniforme verificado por intervalo aos buffers é usar o utilitário gsl::at() na Biblioteca de Suporte de Diretrizes. Também é uma boa prática confiar em implementações padrão de at() disponíveis em contêineres da STL.
Essa regra ajuda a encontrar locais em que o acesso potencialmente não verificado é executado por meio de chamadas para operator[]. Na maioria dos casos, você pode substituir essas chamadas usando gsl::at().
- O acesso a matrizes de tamanho conhecido é sinalizado quando um índice não constante é usado em um operador de índice. Os índices de constantes são tratados pelo STATIC_INDEX_OUT_OF_RANGE C26483.
- A lógica para avisar sobre chamadas sobrecarregadas
operator[]é mais complexa:- Se o índice não for integral, a chamada será ignorada. Isso também lida com a indexação em mapas padrão, uma vez que os parâmetros nesses operadores são passados por referência.
- Se o operador for marcado como não emissor (usando
noexcept,throw()ou__declspec(nothrow)), a chamada será sinalizada. Supomos que, se o operador subscrito nunca lançar exceções, ele não executará verificações de intervalo ou essas verificações serão obscuras. - Se o operador não estiver marcado como não emissor, ele poderá ser sinalizado se for proveniente de um contêiner da STL que também define uma função de membro convencional
at(). Essas funções são detectadas pela simples correspondência de nomes. - A regra não avisa sobre chamadas para funções padrão
at(). Essas funções são seguras; substituí-las porgsl::at()não agregaria muito valor.
- A indexação em
std::basic_string_view<>não é segura, portanto, um aviso é emitido. Substitua ostring_viewpadrão usandogsl::basic_string_span<>, que é sempre marcado por limites. - A implementação não considera verificações de intervalo que o código do usuário pode ter em algum lugar em loops ou ramificações. Aqui, a precisão é trocada por desempenho. Em geral, geralmente você pode substituir verificações explícitas de intervalo usando iteradores mais confiáveis ou loops avançados
formais concisos.
Exemplo
Este exemplo demonstra como a função gsl::at pode substituir uma referência 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';
}