Condividi tramite


Avviso C26449

gsl::span o std::string_view creato da un oggetto temporaneo non sarà valido quando il valore temporaneo viene invalidato (gsl.view)

Linee guida di base di C++: GSL.view: Visualizzazioni.

Gli intervalli e le visualizzazioni sono tipi pratici e leggeri che consentono di fare riferimento ai buffer di memoria. Ma devono essere usati attentamente: mentre l'interfaccia è simile ai contenitori standard, il loro comportamento è più simile al comportamento dei puntatori e dei riferimenti. Non sono proprietari di dati e non devono mai essere costruiti da buffer temporanei. Questo controllo è incentrato sui casi in cui i dati di origine sono temporanei, mentre un intervallo o una vista non è. Questa regola può essere utile per evitare errori sottili ma pericolosi quando il codice legacy viene modernizzato e adotta intervalli o visualizzazioni. Esiste un altro controllo che gestisce uno scenario leggermente diverso che prevede riferimenti a intervalli: C26445 NO_SPAN_REF.

Prendere in considerazione l'uso di C26815 e C26816. Tali avvisi sono versioni più generali di questo avviso.

Osservazioni:

  • Questa regola avvisa in posizioni in cui i costruttori vengono richiamati per intervalli o viste e il buffer dei dati di origine appartiene a un oggetto temporaneo creato nella stessa istruzione. Questo controllo include:

    • conversioni implicite nelle istruzioni return;
    • conversioni implicite negli operatori ternari;
    • conversioni esplicite nelle static_cast espressioni;
    • chiamate di funzione che restituiscono contenitori per valore.
  • I temporaneamente creati per gli argomenti di chiamata di funzione non vengono contrassegnati. È possibile passare intervalli da tali temporaneamente se le funzioni di destinazione non mantengono i puntatori dati nelle variabili esterne.

  • Se gli intervalli o le visualizzazioni sono temporaneamente, la regola li ignora.

  • Il rilevamento dei dati nel controllo presenta alcune limitazioni; pertanto, è possibile che non vengano gestiti scenari complessi che coinvolgono più riassegnazioni oscure.

Nome dell'analisi del codice: NO_SPAN_FROM_TEMPORARY

Esempio

Differenza sottile nei tipi di risultati:

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

Per risolvere il problema, assicurarsi che la visualizzazione venga creata da un oggetto che si trova almeno a condizione che la visualizzazione stessa. A volte è possibile ottenere una soluzione copiando i dati, altre volte è necessario riprogettare alcune API per condividere un riferimento a un oggetto che dura abbastanza a lungo anziché restituire una copia temporanea.

Vedi anche

C26815
C26816