Partilhar via


Advertência C26449

gsl::span ou std::string_view criado a partir de um objeto temporário será inválido quando o objeto temporário for invalidado (gsl.view)

Diretrizes principais do C++: GSL.view: Views.

Espans e visualizações são tipos convenientes e leves que permitem fazer referência a buffers de memória. Mas eles devem ser usados com cuidado: enquanto sua interface se parece com contêineres padrão, seu comportamento é mais parecido com o comportamento de ponteiros e referências. Eles não possuem dados e nunca devem ser construídos a partir de buffers temporários. Esta verificação se concentra nos casos em que os dados de origem são temporários, enquanto um intervalo ou exibição não o é. Essa regra pode ajudar a evitar erros sutis, mas perigosos, cometidos quando o código legado é modernizado e adota extensões ou exibições. Há outra verificação que lida com um cenário ligeiramente diferente envolvendo referências de extensão: C26445 NO_SPAN_REF.

Considere o uso de C26815 e C26816. Esses avisos são versões mais gerais deste aviso.

Observações

  • Esta regra avisa sobre locais onde os construtores são invocados para extensões ou exibições e o buffer de dados de origem pertence a um objeto temporário criado na mesma instrução. Esta verificação inclui:

    • conversões implícitas em declarações de retorno;
    • conversões implícitas em operadores ternários;
    • conversões explícitas em expressões static_cast
    • chamadas de função que retornam contêineres por valor.
  • Os temporários criados para argumentos de chamada de função não são sinalizados. É seguro passar intervalos de tais temporários se as funções de destino não retiverem ponteiros de dados em variáveis externas.

  • Se os vãos ou visualizações forem eles próprios temporários, a regra ignora-os.

  • O rastreamento de dados no verificador tem certas limitações; portanto, cenários complexos envolvendo reatribuições múltiplas ou obscuras podem não ser tratados.

Nome da análise de código: NO_SPAN_FROM_TEMPORARY

Exemplo

Diferença sutil nos tipos de resultados:

// Returns a predefined collection. Keeps data alive.
gsl::span<const sequence_item> get_seed_sequence() noexcept;

// Returns a generated collection. Doesn't own new data.
std::vector<sequence_item> get_next_sequence(gsl::span<const sequence_item>);

void run_batch()
{
    auto sequence = get_seed_sequence();
    while (send(sequence))
    {
        sequence = get_next_sequence(sequence); // C26449
        // ...
    }
}

Para corrigir o problema, certifique-se de que a vista é criada a partir de um objeto que vive pelo menos tanto tempo como a vista em si. Às vezes, uma solução pode ser alcançada copiando os dados, outras vezes algumas APIs precisam ser redesenhadas para compartilhar uma referência a um objeto que vive o suficiente em vez de retornar uma cópia temporária.

Ver também

C26815
C26816