Bagikan melalui


Peringatan C26448

Pertimbangkan untuk menggunakan gsl::finally jika tindakan akhir dimaksudkan (gsl.util)

Pedoman Inti C++: GSL.util: Utilitas

Pustaka Dukungan Pedoman menyediakan utilitas yang nyaman untuk mengimplementasikan konsep tindakan akhir. Karena bahasa C++ tidak mendukung konstruksi try-finally , menjadi umum untuk menerapkan jenis pembersihan kustom yang akan memanggil tindakan arbitrer pada penghancuran. gsl::finally Utilitas diimplementasikan dengan cara ini dan menyediakan cara yang lebih seragam untuk melakukan tindakan akhir di seluruh basis kode.

Ada juga kasus di mana tindakan akhir dilakukan dengan cara gaya C kuno dengan menggunakan goto pernyataan (yang tidak dianjurkan oleh C26438 NO_GOTO). Sulit untuk mendeteksi niat yang tepat dalam kode yang sangat menggunakan goto, tetapi beberapa heuristik dapat membantu menemukan kandidat yang lebih baik untuk pembersihan.

Keterangan

  • Aturan ini ringan dan menggunakan nama label untuk menebak peluang untuk menggunakan objek tindakan akhir.
  • Nama label yang dapat memunculkan peringatan berisi kata-kata seperti "end", "final", "clean", dan sebagainya.
  • Peringatan muncul pada goto pernyataan. Anda mungkin melihat output verbose pada beberapa kesempatan, tetapi output dapat membantu dalam memprioritaskan kode, tergantung pada kompleksitasnya.
  • Aturan ini selalu berpasangan dengan C26438 NO_GOTO. Tergantung pada prioritasnya, salah satu aturan ini dapat dinonaktifkan.

Nama analisis kode: USE_GSL_FINALLY

Contoh

Pembersihan dengan beberapa pernyataan goto:

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();
}

Pembersihan dengan beberapa pernyataan goto digantikan oleh gsl::finally:

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