Udostępnij przez


Ostrzeżenie C26449

gsl::span lub std::string_view utworzony na podstawie parametru tymczasowego będzie nieprawidłowy, gdy tymczasowe jest unieważnione (gsl.view)

Podstawowe wytyczne języka C++: GSL.view: Views.

Zakresy i widoki to wygodne i lekkie typy, które pozwalają odwoływać się do buforów pamięci. Należy jednak używać ich ostrożnie: chociaż interfejs wygląda podobnie do standardowych kontenerów, ich zachowanie jest bardziej podobne do zachowania wskaźników i odwołań. Nie są właścicielami danych i nigdy nie muszą być tworzone z tymczasowych buforów. Ta kontrola koncentruje się na przypadkach, w których dane źródłowe są tymczasowe, podczas gdy zakres lub widok nie jest. Ta reguła może pomóc uniknąć subtelnych, ale niebezpiecznych błędów popełnionych, gdy starszy kod zostanie zmodernizowany i przyjmuje zakresy lub widoki. Istnieje kolejna kontrola, która obsługuje nieco inny scenariusz obejmujący odwołania do zakresu: C26445 NO_SPAN_REF.

Rozważ użycie C26815 i C26816. Te ostrzeżenia są bardziej ogólnymi wersjami tego ostrzeżenia.

Uwagi

  • Ta reguła ostrzega w miejscach, w których konstruktory są wywoływane dla zakresów lub widoków, a bufor danych źródłowych należy do obiektu tymczasowego utworzonego w tej samej instrukcji. Ta kontrola obejmuje następujące elementy:

    • niejawne konwersje w instrukcjach zwrotnych;
    • konwersje niejawne w operatorachternarnych;
    • jawne konwersje w wyrażeniach static_cast ;
    • funkcja wywołuje, które zwracają kontenery według wartości.
  • Tymczasowe utworzone dla argumentów wywołania funkcji nie są oflagowane. Przekazywanie zakresów z takich okresów jest bezpieczne, jeśli funkcje docelowe nie zachowują wskaźników danych w zmiennych zewnętrznych.

  • Jeśli zakresy lub widoki są tymczasowe, reguła je pomija.

  • Śledzenie danych w kontrolerze ma pewne ograniczenia; dlatego złożone scenariusze obejmujące wiele lub niejasne ponowne przydziały mogą nie być obsługiwane.

Nazwa analizy kodu: NO_SPAN_FROM_TEMPORARY

Przykład

Subtelna różnica w typach wyników:

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

Aby rozwiązać ten problem, upewnij się, że widok został utworzony na podstawie obiektu, który znajduje się co najmniej tak długo, jak sam widok. Czasami rozwiązanie można osiągnąć przez skopiowanie danych, a czasami niektóre interfejsy API muszą zostać przeprojektowane, aby udostępnić odwołanie do obiektu, który mieszka wystarczająco długo, zamiast zwracać kopię tymczasową.

Zobacz też

C26815
C26816