In einigen Umgebungen ist die Kompilierung am schnellsten, wenn nur die benötigten Header-Dateien enthalten sind. In anderen Umgebungen wird die Kompilierung optimiert, wenn alle Quelldateien dieselbe primäre Sammlung von Headern verwenden können (einige Dateien enthalten möglicherweise zusätzliche Header, die über die gemeinsame Teilmenge hinausgehen). Im Idealfall sollten Header so erstellt werden, dass mehrere # include-Operationen keine Auswirkung haben. Es kann sinnvoll sein, # include-Anweisungen mit Überprüfungen des Include-Schutzes der einzuschließenden Datei zu umgeben, obwohl dies eine Abhängigkeit vom Format dieses Schutzes schafft. Abhängig vom Dateicaching-Verhalten eines Systems kann es außerdem nicht lange dauern, bis ein unnötiger # Include, dessen Ziel am Ende vollständig # ifdef'ed ist, entfernt wird.
Eine andere zu berücksichtigende Sache ist, dass, wenn eine Funktion einen Zeiger auf eine Struktur nimmt, man den Prototyp als schreiben kann
void foo (struct BAR_s * bar);
ohne dass eine Definition für BAR_s im Gültigkeitsbereich liegen muss. Ein sehr praktischer Ansatz zur Vermeidung unnötiger Einschlüsse.
PS: In vielen meiner Projekte wird es eine Datei geben, von der erwartet wird, dass jedes Modul #include enthält, die Dinge wie typedefs für ganzzahlige Größen und einige gemeinsame Strukturen und Vereinigungen enthält [z
typedef union {
unsigned long l;
unsigned short lw [2];
vorzeichenloses Zeichen lb [4];
} U_QUAD;
(Ja, ich weiß, dass ich in Schwierigkeiten geraten würde, wenn ich zu einer Big-Endian-Architektur wechseln würde. Da mein Compiler jedoch keine anonymen Strukturen in Unions zulässt, muss für die Verwendung benannter Bezeichner für die Bytes innerhalb der Union auf sie zugegriffen werden theUnion.b.b1 usw., was ziemlich nervig erscheint.