C26438 NO_GOTOC26438 NO_GOTO

« Éviter 'goto'. »"Avoid 'goto'."

Instructions de base C++: ES.76 : éviter gotoC++ Core Guidelines: ES.76: Avoid goto

À l’aide de 'goto' est largement reconnue en pratique dangereuse et sujette à erreurs.Using of ‘goto’ is widely acknowledged as dangerous and error-prone practice. Il est acceptable uniquement dans le code généré (par exemple, dans un analyseur généré à partir d’une grammaire).It is acceptable only in generated code (e.g. in a parser generated from a grammar). Avec des fonctionnalités C++ modernes et utilitaires fournis par la bibliothèque de prise en charge les instructions doit être facile à éviter 'goto'.With modern C++ features and utilities provided by the Guidelines Support Library it should be easy to avoid ‘goto’ altogether.

NotesRemarks

  • Cette règle vous avertit sur toute occurrence de 'goto', même s’il s’agit de code mort, sauf le code de modèle qui n’est jamais utilisé et par conséquent ignorée par le compilateur.This rule warns on any occurrence of ‘goto’, even if it happens in dead code, except template code which is never used and hence ignored by compiler.
    • Avertissements peuvent être bruyantes si elles rencontrent une macro contenant 'goto'.Warnings can be noisy if they encounter a macro containing ‘goto’. Mécanisme de création de rapports actuel pointez sur toutes les instances où cette macro se développe.Current reporting mechanism would point to all instances where such macro gets expanded. Mais le correctif généralement faire dans un seul emplacement, la modification de la macro ou éviter l’utilisation de celui-ci et en exploitant plusieurs mécanismes facile à gérer.But the fix can usually be done in one place by changing the macro or avoiding use of it and leveraging more maintainable mechanisms. ## ExempleExample 'goto cleanup' dans la macro‘goto cleanup’ in macro
#define ENSURE(E, L) if (!(E)) goto L;

void poll(connection &c)
{
    ENSURE(c.open(), end);                  // C26438

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        ENSURE(c.read_header(h), end);      // C26438
        ENSURE(c.read_signature(s), end);   // C26438
        // ...
    }

end:
    c.close();
}

ExempleExample

'goto cleanup' dans la macro - remplacé par gsl::finally‘goto cleanup’ in macro - replaced with gsl::finally

void poll(connection &c)
{
    auto end = gsl::finally([&c] { c.close(); });

    if (!c.open())
        return;

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if(!c.read_header(h))
            return;
       if(!c.read_signature(s))
            return;
        // ...
    }
}