Aracılığıyla paylaş


Uyarı C26448

Son eylemin amaçlanmış olup olmadığını kullanmayı gsl::finally göz önünde bulundurun (gsl.util)

C++ Temel Yönergeleri: GSL.util: Yardımcı Programlar

Yönergeler Destek Kitaplığı, son eylem kavramını uygulamak için kullanışlı bir yardımcı program sağlar. C++ dili try-finally yapılarını desteklemediğinden, yok etme üzerinde rastgele eylemler çağıracak özel temizleme türlerinin uygulanması yaygın hale geldi. yardımcı gsl::finally programı bu şekilde uygulanır ve bir kod tabanında son eylemleri gerçekleştirmek için daha tekdüzen bir yol sağlar.

Son eylemlerin deyimleri kullanılarak goto eski moda C stilinde gerçekleştirildiği durumlar da vardır (C26438 NO_GOTO tarafından önerilmez). Yoğun olarak kullanılan gotokodda tam amacı saptamak zordur, ancak bazı buluşsal yöntemler temizleme için daha iyi adaylar bulmanıza yardımcı olabilir.

Açıklamalar

  • Bu kural basit bir kuraldır ve son eylem nesnelerini kullanma fırsatlarını tahmin etmek için etiket adlarını kullanır.
  • Uyarı oluşturabilen etiket adları "end", "final", "clean" gibi sözcükler içerir.
  • Uyarılar deyimlerinde goto görünür. Bazı durumlarda ayrıntılı çıkış görebilirsiniz, ancak çıktı, karmaşıklık düzeyine bağlı olarak kodun önceliğini belirlemeye yardımcı olabilir.
  • Bu kural her zaman C26438 NO_GOTO ile eşleştirilmektedir. Önceliklere bağlı olarak, bu kurallardan biri devre dışı bırakılabilir.

Kod analizi adı: USE_GSL_FINALLY

Örnek

Birden çok goto deyimiyle temizleme:

void poll(connection_info info)
{
    connection c = {};
    if (!c.open(info))
        return;

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if (!c.read_header(h))
            goto end;               // C26448 and C26438
        if (!c.read_signature(s))
            goto end;               // C26448 and C26438
        // ...
    }

end:
    c.close();
}

ile değiştirilen gsl::finallybirden çok goto deyimiyle temizleme:

void poll(connection_info info)
{
    connection c = {};
    if (!c.open(info))
        return;

    auto end = gsl::finally([&c] { c.close(); });
    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if (!c.read_header(h))
            return;
        if (!c.read_signature(s))
            return;
        // ...
    }
}