Führen Sie einen bestimmten Clang-Tidy-Check für Ihre gesamte Codebasis durch

Führen Sie einen bestimmten Clang-Tidy-Check für Ihre gesamte Codebasis durch

Kürzlich habe ich einen großen Codeabschnitt umgestaltet, der Tausende von Codezeilen umfasste, die auf die eine oder andere Weise mit der Verarbeitung von Strings zu tun hatten. Der gesamte Code verarbeitete char* (Zeigerarrays im C-Stil) und das Konzept von const oder Eigentum war in diesem Teil der Codebasis buchstäblich unbekannt. Der umgestaltete Code verwendet std::string , aber aufgrund der Vermächtnisnatur gab eine große Anzahl von Methoden nullptr zurück 's anstelle von leeren Zeichenfolgen (wie "" ). Ich verstehe, warum das gemacht wurde, aber all diese Instanzen zu finden und die Tatsache, dass es nur einen Laufzeitfehler gibt, war ein bisschen schade.

Zum Glück clang-tidy ist hier, um den Tag zu retten. In meiner IDE, CLion, gibt es eine Warnung aus, wenn Sie einen nullptr zurückgeben . Dies geschieht jedoch nur in der Datei, die Sie gerade bearbeiten, und da es sich um Millionen von Dateien handelt, wollte ich sie nicht von Hand öffnen. Sie können clang-tidy ausführen leicht auf einer Datei, und es ist nicht schwer, es mit dem Skript run-clang-tidy.py auch auf einer gesamten Codebasis auszuführen , die in ihren Paketen enthalten sind.

Dieses Snippet zeigt Ihnen, wie Sie einen bestimmten clang-tidy ausführen Überprüfen Sie in meinem Fall bugprone-string-constructor , auf einer (cmake und C++) Codebasis.

Hier ist die Clang-Tidy-Nachricht in CLion:

Beispielcode mit undefiniertem Verhalten

Dies ist ein Beispielcode, der das Verhalten demonstriert:

#include <string>
#include <iostream>

class Example {
public:
    std::string getName() { return nullptr; }
};

int main() {
    Example ex;
    std::cout << "Example: " << ex.getName() << std::endl;
    return 0;
}

Wenn Sie versuchen, das obige Codebeispiel auszuführen, erhalten Sie einen Laufzeitfehler:

terminate called after throwing an instance of 'std::logic_error'
    what():  basic_string::_M_construct null not valid

Meinungen zu nullptr und std::string variieren, je nachdem, wen Sie fragen, aber derzeit ist es nicht möglich, einen std::string zu konstruieren mit anullptr .

Lassen Sie clang-tidy auf Ihrer gesamten Codebasis laufen

Stellen Sie sicher, dass Sie clang-tidy haben installiert:

apt install clang-tidy

Navigieren Sie in Ihren Projektordner:

cd my/cpp/project

Falls noch nicht geschehen, erstellen Sie einen Build-Ordner (mkdir build; cd build ) und führen Sie cmake aus mit einem zusätzlichen Flag, um die Kompilierungsdatenbank fürclang-tidy zu erstellen :

cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Debug 

Führen Sie im Build-Ordner run-clang-tidy aus . Es könnte ein anderer Befehl sein (run-clang-tidy.py oder run-clang-tidy-VERSIONNUMBER ) abhängig von der Paketpräferenz Ihrer Distribution.

run-clang-tidy -extra-arg=-Wno-unknown-warning-option -checks='-*,bugprone-string-constructor' 2>&1 | tee -a clang-tidy-result

Dies wird eine Weile dauern, wenn der Befehl beendet ist, können Sie sich die Ergebnisse ansehen oder in der Datei clang-tidy-result . In meinem Fall gab es bestimmte Dateinamen und Zeilennummern an, wo es das undefinierte Verhalten fand.

Der -extra-arg aufgrund eines anderen Compiler-Erweiterungs-Flags für unseren Code erforderlich war, können Sie das wahrscheinlich weglassen.

Die -checks='-*' deaktiviert alle Prüfungen, die nächste,bugprone-string-constructor aktiviert nur die spezifische Zeichenfolgenprüfung, die ich ausführen möchte. Sie können spezifischere Prüfungen hinzufügen, trennen Sie diese durch ein Komma. Ein Beispiel mit nur 2 aktivierten Prüfungen:

-checks='-*,bugprone-string-constructor,bugprone-string-integer-assignment'

Eine aktuelle Liste von clang-tidy Schecks finden Sie auf der LLVM-Website.


No