header files / unnötige #include-Direktiven ?



  • Hallo,

    ich suche nach einem Tool unter Linux oder Windows, dass in einem Verzeichnisbaum alle .C-Dateien durchsucht und prüft, ob es unnötige #include-Direktiven gibt,
    d.h. ob der Inhalt einer includierten Headerdatei überhaupt im .C-File benutzt wird.

    Ich möchte gerne diese Fälle automatisiert identifizieren und ein Protokoll erstellen lassen, dass Aussage darüber macht, welche #include-Zeilen man in welchen .C source Files entfernen kann. 😕

    Besten Dank

    Rainer



  • CLion (IDE) kann dir unnötige includes anzeigen. Mehr tools kenne ich nicht.



  • Das steht auf meiner inneren "sollte man mal ein Werkzeug bauen"-Liste. Einfachster Ansatz, der mir einfällt: #includes einzeln entfernen und versuchen zu kompilieren. Wenn das Kompilieren fehlschlägt, war der Header wohl notwendig. Interessant wird es, wenn ein Header auf einer Plattform notwendig ist und auf der anderen nicht.



  • TyRoXx schrieb:

    Das steht auf meiner inneren "sollte man mal ein Werkzeug bauen"-Liste. Einfachster Ansatz, der mir einfällt: #includes einzeln entfernen und versuchen zu kompilieren. Wenn das Kompilieren fehlschlägt, war der Header wohl notwendig. Interessant wird es, wenn ein Header auf einer Plattform notwendig ist und auf der anderen nicht.

    Nicht gut, wenn man das Tool wiederholt ausführt. Die C-Datei sollte alle Header inkludieren, die sei selber braucht. Für Perl hatte ich mal einen Automaten gebaut, der schaut, welche Dateien von welchen abhöngen, indem er den Quellcode liest. Man musste halt stets mit voll qualifizierten Namen proggern. Aber dafür hatte der Irc-Bot zur Laufzeit feststellen können, welche Module neu geladen werden müssen und hat minimal neugeladen, vor allem bei nur neuen Anti-Troll-Regeln oder neuen Befehlen musste er nicht hochgehen bis zum Modul, was die Connection offenhält.

    Zurück zu C. Oh, ich brauche "eup/glob.h" nicht mehr, weil ich glob() nicht mehr verwende. Oh, meine 500k-große "server.c" compiliert nicht mehr, weil printf, malloc, Sleep und foo und 100 weitere nicht mehr deklariert sind. Dein Tool hat mir im letzten halben Jahr 50 Headers entfernt, die von "eup/glob.h" eh inkludiert werden. Nu muss ich 50 Headers nachträglich wieder einfügen. Ich will nicht die "eup/glob.h" mehr haben, weil ich die Lizenz nicht mehr habe.

    Das Tool müßte also schon wein wenig mehr Grips haben, also bloß rumzuprobieren.
    Das Inkludieren eines Headers wie <unistd> weil ich sleep() verwende, der zufällig schon in "eup/glob.h" auch inkludiert wurde, wenn ich glob() verwende und darum "eup/glob.h" brauche, kostet mal rein gar nix. Die muss man nicht rausmachen und SOLL man nicht rausmachen. Auf Win hat man #pragma once, auf Lin auch, aber brauchts nichtmal, weil der Compiler #ifndef-Headerguards erkennt und sich das #pragma once selber denkt.

    Kosten habe ich bei Headers, die ich inkludiere, ohne daß ich sie überhaupt brauche. Allem voran die <windows.h>, selbst mit Compilerfeature "precompiled headers" ist das Biest einfach nur teuer. Ok, der Header wird, wenn er precompiled ist, viel schneller eingelesen als roh, aber noch viel viel schneller ist es, ihn gar nicht einzulesen. Und sie ist qusi automatisch überall mittelbar drin, irgendeine Klasse Semaphore/FileMapping/Mutex/Threadpool/ClientSocket/MemPage/… benutzt man doch überall, die dann ein HANDLE als Attribut hat, also nicht direkt, aber MapTile/FastVector/MemPool/XMLWriter/BTree/… dann schon, also eigentlich in jeder Übersetzungseinheit irgendwo mittelbar eine Kleinigkeit, die Betriebssystemabhängig implemetiert ist (türlich mit gleicher Schnittstelle auf alles BS). Das Monster einzusparen, wegzupimpeln und so bringt mal Faktor 10, die <iostream> ist ähnlich lahm, wir aber viel weniger gebraucht.
    Ein typedef void* HANDLE in der "windows_fwd.h" nebst einem static_assert(is_same_type(void*,HANDLE)) nach #include <windows.h> in der "windows_fwd.cpp" bringt dann den Speed.
    Das wiederum kann man gerne #ifdefen, um im Debug-Build volle Compile-Geschwindigkeit zu haben und im Release-Build sind die elementaren das BS abstrahierende Wrapper-Funktionen inline nebst #include <windows.h> in diesen Dateien. Oder je nach Gusto LinkTimeOptimierung im Release-Build anmachen oder mixen.

    Dazu noch ein schnelles Debug-Logging und ein eigenes ASSERT-Makro, das zum Beispiel falls der Debugger mitläuft __asm int 3 benutzt, und alles ist in Butter.


Log in to reply