Partager via


Avertissement C26449

gsl::span ou std::string_view créé à partir d’un temporaire n’est pas valide lorsque le temporaire est invalidé (gsl.view)

Instructions principales C++ : GSL.view : Vues.

Les étendues et les vues sont des types pratiques et légers qui vous permettent de référencer des mémoires tampons. Mais ils doivent être utilisés avec soin : alors que leur interface ressemble à des conteneurs standard, leur comportement est plus semblable au comportement des pointeurs et des références. Ils ne possèdent pas de données et ne doivent jamais être construits à partir de mémoires tampons temporaires. Cette vérification se concentre sur les cas où les données sources sont temporaires, tandis qu’une étendue ou une vue ne l’est pas. Cette règle peut aider à éviter les erreurs subtiles mais dangereuses commises lorsque le code hérité est modernisé et adopte des étendues ou des vues. Il existe une autre vérification qui gère un scénario légèrement différent impliquant des références d’étendue : C26445 NO_SPAN_REF.

Envisagez d’utiliser C26815 et C26816. Ces avertissements sont des versions plus générales de cet avertissement.

Notes

  • Cette règle avertit les emplacements où les constructeurs sont appelés pour des étendues ou des vues et que la mémoire tampon de données source appartient à un objet temporaire créé dans la même instruction. Cette vérification inclut :

    • conversions implicites dans les instructions return ;
    • conversions implicites dans les opérateurs ternaires ;
    • conversions explicites dans les static_cast expressions ;
    • les appels de fonction qui retournent des conteneurs par valeur.
  • Les arguments d’appel de fonction créés temporairement ne sont pas marqués. Il est sûr de passer des étendues de ce type temporaires si les fonctions cibles ne conservent pas de pointeurs de données dans des variables externes.

  • Si des étendues ou des vues sont temporaires, la règle les ignore.

  • Le suivi des données dans le vérificateur présente certaines limitations ; par conséquent, des scénarios complexes impliquant plusieurs réaffectations obscures peuvent ne pas être gérés.

Nom de l’analyse du code : NO_SPAN_FROM_TEMPORARY

Exemple

Différence subtile dans les types de résultats :

// 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
        // ...
    }
}

Pour résoudre le problème, assurez-vous que la vue est créée à partir d’un objet qui vit au moins tant que la vue elle-même. Parfois, une solution peut être obtenue en copiant les données, d’autres fois que certaines API doivent être repensées pour partager une référence à un objet qui dure suffisamment longtemps au lieu de retourner une copie temporaire.

Voir aussi

C26815
C26816