HAFTUNGSAUSSCHLUSS: Mein Tagesjob besteht darin, für ein Unternehmen zu arbeiten, das statische Analysewerkzeuge entwickelt.
Es würde mich wundern, wenn die meisten (wenn nicht alle) statischen Analysetools keine Form der Überprüfung der Header-Nutzung hätten. Sie können diese Wikipedia-Seite verwenden, um eine Liste der verfügbaren Tools abzurufen und die Unternehmen per E-Mail zu fragen.
Einige Punkte, die Sie bei der Bewertung eines Tools berücksichtigen sollten:
Bei Funktionsüberladungen möchten Sie, dass alle Header mit Überladungen sichtbar sind, nicht nur der Header, der die Funktion enthält, die durch die Überlastungsauflösung ausgewählt wurde:
void foo (char);
void foo (int);
#include "f1.h"
#include "f2.h"
int main ()
{
foo (0);
}
Wenn Sie den Brute-Force-Ansatz wählen, entfernen Sie zuerst alle Header und fügen Sie sie erneut hinzu, bis sie kompiliert werden. Wenn zuerst 'f1.h' hinzugefügt wird, wird der Code kompiliert, aber die Semantik des Programms wurde geändert.
Eine ähnliche Regel gilt, wenn Sie Teil- und Spezialisierungen haben. Es spielt keine Rolle, ob die Spezialisierung ausgewählt ist oder nicht, Sie müssen sicherstellen, dass alle Spezialisierungen sichtbar sind:
template <typename T>
void foo (T);
template <>
void foo (int);
#include "f1.h"
#include "f2.h"
int main ()
{
foo (0);
}
Was das Überlastungsbeispiel betrifft, kann der Brute-Force-Ansatz zu einem Programm führen, das zwar noch kompiliert wird, aber ein anderes Verhalten aufweist.
Eine andere verwandte Art der Analyse, auf die Sie achten können, ist die Überprüfung, ob Typen vorwärts deklariert werden können. Folgendes berücksichtigen:
class A { };
#include "A.h"
void foo (A const &);
#include "foo.h"
void bar (A const & a)
{
foo (a);
}
Im obigen Beispiel ist die Definition von 'A' nicht erforderlich, daher kann die Header-Datei 'foo.h' so geändert werden, dass sie nur für 'A' eine Vorwärtsdeklaration enthält:
class A;
void foo (A const &);
Diese Art der Überprüfung reduziert auch die Header-Abhängigkeiten.