Megosztás:


Figyelmeztetés C26449

gsl::span vagy std::string_view egy ideiglenesből létrehozott elem érvénytelen lesz, ha az ideiglenes érvényét veszti (gsl.view)

C++ alapvető irányelvek: GSL.view: Nézetek.

A spánok és nézetek kényelmes és könnyű típusok, amelyek lehetővé teszik a memóriapufferekre való hivatkozást. Azonban körültekintően kell használni őket: míg a felületük a standard tárolókhoz hasonlóan néz ki, viselkedésük inkább a mutatók és hivatkozások viselkedéséhez hasonlít. Nem rendelkeznek adatokkal, és soha nem szabad ideiglenes pufferekből összeállítani őket. Ez az ellenőrzés azokra az esetekre összpontosít, amikor a forrásadatok ideiglenesek, míg a span vagy a nézet nem. Ez a szabály segíthet elkerülni a finom, de veszélyes hibákat, amikor az örökölt kód modernizálódik, és kiterjedéseket vagy nézeteket fogad el. Van egy másik ellenőrzés, amely egy kissé eltérő forgatókönyvet kezel, amely span-hivatkozásokat tartalmaz: C26445 NO_SPAN_REF.

Fontolja meg a C26815 és a C26816 használatát. Ezek a figyelmeztetések a figyelmeztetés általánosabb verziói.

Megjegyzések

  • Ez a szabály figyelmezteti azokat a helyeket, ahol a konstruktorok spanokra vagy nézetekre lesznek meghívva, és a forrásadat-puffer az ugyanabban az utasításban létrehozott ideiglenes objektumhoz tartozik. Ez az ellenőrzés a következőket tartalmazza:

    • implicit konverziók a visszatérési utasításokban;
    • implicit konverziók ternáris operátorokban;
    • explicit konverziók kifejezésekben static_cast ;
    • függvényhívások, amelyek érték szerint adnak vissza tárolókat.
  • A függvényhívási argumentumokhoz létrehozott ideiglenes elemek nincsenek megjelölve. Biztonságos az ilyen ideiglenes tartományok átadása, ha a célfüggvények nem tartják meg az adatmutatókat külső változókban.

  • Ha a spanok vagy nézetek maguk is ideiglenesek, akkor a szabály kihagyja őket.

  • Az adatkövetés az ellenőrzőben bizonyos korlátozásokkal rendelkezik; ezért nem kezelhetők olyan összetett forgatókönyvek, amelyek több vagy homályos hozzárendelést foglalnak magukban.

Kódelemzés neve: NO_SPAN_FROM_TEMPORARY.

példa

Apró különbség az eredménytípusokban:

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

A probléma megoldásához győződjön meg arról, hogy a nézet olyan objektumból lett létrehozva, amely legalább addig él, amíg maga a nézet is él. Előfordulhat, hogy az adatok másolásával lehet megoldást elérni, máskor azonban egyes API-kat újra kell tervezni, hogy egy olyan objektumra mutató hivatkozást osszanak meg, amely elég hosszú ideig él az ideiglenes másolat visszaadása helyett.

Lásd még

C26815
C26816