Uyarı C26449
gsl::span
veyastd::string_view
geçici bir öğeden oluşturulanlar, geçici geçersiz kılındığında geçersiz olur (gsl.view)
C++ Temel Yönergeleri: GSL.view: Görünümler.
Spans ve görünümler, bellek arabelleklerine başvurmanızı sağlayan kullanışlı ve basit türlerdir. Ancak bunların dikkatli bir şekilde kullanılması gerekir: arabirimleri standart kapsayıcılara benzer olsa da, davranışları daha çok işaretçilerin ve başvuruların davranışına benzer. Bunlar veriye sahip değildir ve hiçbir zaman geçici arabelleklerden oluşturulamaz. Bu denetim, bir yayılma alanı veya görünüm değilken kaynak verilerin geçici olduğu durumlara odaklanır. Bu kural, eski kod modernleştirildiğinde ve yayılma alanları veya görünümleri benimsediğinde yapılan küçük ama tehlikeli hatalardan kaçınmaya yardımcı olabilir. Span başvurularını içeren biraz farklı bir senaryoya yönelik başka bir denetim daha vardır: C26445 NO_SPAN_REF.
C26815 ve C26816 kullanmayı göz önünde bulundurun. Bu uyarılar, bu uyarının daha genel sürümleridir.
Açıklamalar
Bu kural, oluşturucuların yayılma alanları veya görünümler için çağrıldığı ve kaynak veri arabelleğinin aynı deyimde oluşturulan geçici bir nesneye ait olduğu yerlerde uyarır. Bu denetim şunları içerir:
- return deyimlerinde örtük dönüştürmeler;
- üçüncül işleçlerde örtük dönüştürmeler;
- ifadelerde
static_cast
açık dönüştürmeler; - değere göre kapsayıcı döndüren işlev çağrıları.
İşlev çağrısı bağımsız değişkenleri için oluşturulan geçici değerler işaretlenmez. Hedef işlevler dış değişkenlerde veri işaretçilerini tutmazsa, bu tür geçici sürelerden yayılmaları geçirmek güvenlidir.
Yayılma alanları veya görünümler kendileri geçiciyse, kural bunları atlar.
Denetleyicide veri izlemenin belirli sınırlamaları vardır; Bu nedenle, birden çok veya belirsiz yeniden atama içeren karmaşık senaryolar işlenmeyebilir.
Kod analizi adı: NO_SPAN_FROM_TEMPORARY
Örnek
Sonuç türlerinde küçük fark:
// 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
// ...
}
}
Sorunu çözmek için görünümün en az görünümün kendisi kadar uzun süre yaşayan bir nesneden oluşturulduğundan emin olun. Bazen verileri kopyalayarak bir çözüm elde edilebilir, diğer zamanlarda bazı API'lerin geçici bir kopya döndürmek yerine yeterince uzun süre yaşayan bir nesneye başvuruyu paylaşmak için yeniden tasarlanması gerekir.