Forum: PC-Programmierung C: Umgang mit (verschachtelten) Headerfiles


von Ralf (Gast)


Lesenswert?

Hallo,

mich würde interessieren, wie ihr mit (teils verschachtelten) 
Headerfiles umgeht.

Konkretes Beispiel: Ich verwende eine Headerdatei, in der ich mittels 
"typedef" die Kurzschreibweisen für die Datentypen realisiert habe, also 
"typedef unsigned char uchar;" etc.

Im C-Sourcefile verweise ich logischerweise auf diese Headerdatei. Die 
Headerdatei, welche die Prototypen für die im C-Sourcefile enthaltenen 
Funktionen bereitstellt, muss ja diese Kurzschreibweisen auch kennen.

So, jetzt stelle ich mir die Frage, ob es für einen guten Stil 
ausreicht, die Headerdatei der Kurzschreibweisen ganz am Anfang jeder 
C-Sourcedatei einzubinden, oder in der entsprechenden Headerdatei 
(=verschachtelt) oder sogar beides.
Im ersten Fall sieht ein User sofort, dass was zusätzlich "nötig" ist. 
Im zweiten Fall ist das nicht offensichtlich, verkürzt aber den 
"include"-Block.

Das "Problem" lässt sich noch weiter ausbauen: Mal angenommen, ich habe 
ein Sourcefile, welches Funktionen eines anderen Sourcefiles verwendet 
(was ja zwangsläufig fast immer der Fall ist). Habe ich die 
"include"-Anweisungen im zugehörigen Headerfile ist es wieder nicht 
sofort ersichtlich, auf welchen Funktionen aufgebaut wird, aber der 
#include-Block ist wiederum kürzer und es stellt sicher, dass immer alle 
nötigen #include-Anweisungen vorhanden sind und keine vergessen wurden. 
Beispielsweise kann der C51-Compiler von Keil am besten optimieren, wenn 
jede Funktion ein eigenes Sourcefile hat, da wäre dann viel Copy&Paste 
nötig (was nicht weh tut), aber nachträglich eine Headerdatei in mehrere 
betroffene Sourcefiles zu bringen würde schon eher wehtun.

Wie macht ihr das so?

Ralf

von Karl H. (kbuchegg)


Lesenswert?

Ralf schrieb:
> Hallo,
>
> mich würde interessieren, wie ihr mit (teils verschachtelten)
> Headerfiles umgeht.
>
> Konkretes Beispiel: Ich verwende eine Headerdatei, in der ich mittels
> "typedef" die Kurzschreibweisen für die Datentypen realisiert habe, also
> "typedef unsigned char uchar;" etc.

Das ist keine gute Idee.
Mitlerweile gibt es dafür brauchbare standardisierte Datentypnamen. OK, 
das ist jetzt nicht das Thema. Daher diese Info nur nebenbei

> So, jetzt stelle ich mir die Frage, ob es für einen guten Stil
> ausreicht, die Headerdatei der Kurzschreibweisen ganz am Anfang _jeder_
> C-Sourcedatei einzubinden, oder in der entsprechenden Headerdatei
> (=verschachtelt) oder sogar beides.

Gewöhn dir folgendes an.
Jedes File, egal ob Source oder Header, inkludiert grundsätzlich alles, 
was es für sich selbst benötigt.

Im Header kommt ein uchar vor?
Dann inkludiert das Header File auch dasjenige File, welches den uchar 
bereitstellt.

In einem C File kommt ein uchar vor?
Dann inkludiert dieses C File auch dasjenige File, welches den uchar 
bereitstellt. Und zwar unabhängig davon, ob es nicht auch schon einen 
anderen Include gäbe, der den uchar-Header auch inkludieren würde. 
Lediglich das eigene Header File kann man davon ausnehmen. Man sieht 
also das eigene Header File als die Schnittstellenbeschreibung für sich 
selbst an. Und da die Schnittstellenbeschreibung schon einen uchar 
bereitgestellt hat, ist das dann in der Implementierung nicht mehr 
nötig.

Eine Zeitlang kommt man damit über die Runden:
Ach den Header brauch ich jetzt nicht, ich inkludiere ja sowieso xyz.h 
und die zieht mir dann den Header schon rein.

Aber irgendwann ist man in der Situation, das eine winzige Änderung in 
einem Header File eine Menge anderer Source Code Files unkompilierbar 
macht. Und dann ist die Verzweiflung gross, das alles wieder zu 
reparieren.


> sofort ersichtlich, auf welchen Funktionen aufgebaut wird, aber der
> #include-Block ist wiederum kürzer

Vergiss die Länge des Include Blocks.
Die ist uninteressant. Wenn du Unmengen includen musst, stehen die 
Chancen gut, dass das File sowieso an sich schon zuviel enthält.

> Wie macht ihr das so?

Einfache Regel:
Jedes File included was es benötigt.

von Oliver R. (superberti)


Lesenswert?

Yepp, das kann ich so auch bestätigen.

Headerhygiene wird vor allen Dingen bei großen Projekten sehr wichtig, 
da durch exzessives Rekursiv-Includieren die Kompilerzeiten extrem 
ansteigen! Bei einem kleinen Bastelprojekt merkt das noch keiner, wenn 
man aber so wie wir den Compiler mit 10^6 Zeilen Code foltert, dann 
macht es gewaltige Unterschiede in der Vorgehensweise.
Ich habe vor etlichen Jahren gezielt unsere Header entrümpelt und konnte 
damit die Kompilierzeit auf 1/4 (!) runterdrücken.
Manchmal ist es auch sinnvoll, im Header benötigte Typen forward zu 
deklarieren und erst später im .c/.cpp zu inkludieren.
Es gibt nämlich "nervige" Header, vor allem von externen Libs, die zur 
korrekten Kompilation bestimmte defines in den Projektoptionen 
benötigen. Und wenn jetzt jemand solch einen Header in einem anderen, 
häufig benutzten Header inkludiert, dann müssen alle anderen Projekte 
auch diese defines bekommen, was immer für viel Freude sorgt ;-)

Gruß, Oliver

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.