Warnung C26448

Erwägen Sie die Verwendung gsl::finally , wenn die endgültige Aktion vorgesehen ist (gsl.util)

C++ Core Guidelines: GSL.util: Utilities

Die Richtlinienunterstützungsbibliothek bietet ein praktisches Hilfsprogramm zum Implementieren des endgültigen Aktionskonzepts . Da die C++-Sprache keine Konstrukte unterstützt, wurde es üblich, benutzerdefinierte sauber up-Typen zu implementieren, die willkürliche Aktionen zur Zerstörung aufrufen würden. Das gsl::finally Hilfsprogramm wird auf diese Weise implementiert und bietet eine einheitlichere Möglichkeit, endgültige Aktionen über eine Codebasis hinweg auszuführen.

Es gibt auch Fälle, in denen endgültige Aktionen mithilfe von Anweisungen (die von C26438 NO_GOTO abgeraten werden) auf altmodische Weise durchgeführt goto werden. Es ist schwierig, die genaue Absicht im Code zu erkennen, der stark verwendet gotowird, aber einige Heuristiken können helfen, bessere Kandidaten für sauber up zu finden.

Hinweise

  • Diese Regel ist einfach und verwendet Bezeichnungsnamen, um möglichkeiten zur Verwendung endgültiger Aktionsobjekte zu erraten.
  • Bezeichnungsnamen, die eine Warnung auslösen können, enthalten Wörter wie "end", "final", "sauber" usw.
  • Warnungen werden in den goto Anweisungen angezeigt. Es kann vorkommen, dass eine ausführliche Ausgabe angezeigt wird, aber die Ausgabe kann je nach Komplexität beim Priorisieren von Code hilfreich sein.
  • Diese Regel wird immer in Kombination mit C26438-NO_GOTO verwendet. Abhängig von den Prioritäten kann eine dieser Regeln deaktiviert werden.

Codeanalysename: USE_GSL_FINALLY

Beispiel

Bereinigung mit mehreren Goto-Anweisungen:

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

Bereinigung mit mehreren Goto-Anweisungen ersetzt durch 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;
        // ...
    }
}