Avviso C26449
gsl::span
ostd::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.