Partager via


Avertissement C26448

Envisagez d’utiliser gsl::finally si l’action finale est prévue (gsl.util)

Instructions principales C++ : GSL.util : Utilitaires

La bibliothèque de prise en charge des instructions fournit un utilitaire pratique pour implémenter le concept d’action final. Étant donné que le langage C++ ne prend pas en charge les constructions try-finally , il est devenu courant d’implémenter des types de nettoyage personnalisés qui appellent des actions arbitraires lors de la destruction. L’utilitaire gsl::finally est implémenté de cette façon et offre un moyen plus uniforme d’effectuer des actions finales dans une base de code.

Il existe également des cas où les actions finales sont effectuées de manière ancienne en C à l’aide goto d’instructions (ce qui est déconseillé par C26438 NO_GOTO). Il est difficile de détecter l’intention exacte dans le code qui utilise gotofortement , mais certaines heuristiques peuvent aider à trouver de meilleurs candidats pour le nettoyage.

Notes

  • Cette règle est légère et utilise des noms d’étiquettes pour deviner les opportunités d’utiliser des objets d’action finals.
  • Les noms d’étiquettes qui peuvent déclencher un avertissement contiennent des mots tels que « end », « final », « clean », et ainsi de suite.
  • Les avertissements apparaissent dans les goto instructions. Vous pouvez voir une sortie détaillée à certaines occasions, mais la sortie peut aider à hiérarchiser le code, en fonction de sa complexité.
  • Cette règle est toujours associée à la NO_GOTO C26438. Selon les priorités, l’une de ces règles peut être désactivée.

Nom de l’analyse du code : USE_GSL_FINALLY

Exemple

Nettoyage avec plusieurs instructions 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();
}

Nettoyage avec plusieurs instructions goto remplacées par 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;
        // ...
    }
}