Forum: Mikrocontroller und Digitale Elektronik Unnötige Headerfiles eingebunden


von Hans (Gast)


Lesenswert?

Hallo,

was passiert genau, wenn man Header Files einbindet, die man gar nicht 
benötigt.

Wird der compilierte Code größer oder wird nur die Compilierzeit größer?

Was kann sonst noch passieren?

von Martin H. (marrtn)


Lesenswert?

Kommt darauf an, was in den Headerfiles steht...

von Phantomix X. (phantomix)


Lesenswert?

Ein #include ist so, als ob du den Inhalt der Headerdatei an dieser 
Stelle in den Code einfügst, mit allen Konsequenzen.

Die Compilierzeit nimmt auf jeden Fall zu.

Bei unsauber programmierter SW (bspw Leute, die Variablen in 
Headerdateien anlegen) nimmt auch die Codegröße zu und es kann zu 
Compilerfehlern kommen usw.

(nicht nur) Meine Faustregel ist, in Headerdateien gehört nichts, was am 
Ende Platz benötigt. Außerdem sollte jede Headerdatei so gut es geht 
eigenständig sein - In headerdateien möglichst nicht andere includieren. 
Auf die Weise hat man überhaupt keine Probleme damit, auch wenn man 
Headerdateien einbindet die man nicht braucht.

von Hans (Gast)


Lesenswert?

Nehmen wir mal an ganz "normale" Header Files. Also Funktionsprototypen 
und vielleicht "extern" Variablen mit zugehörigem C-File.

von Dr. Sommer (Gast)


Lesenswert?

Phantomix Ximotnahp schrieb:
> Außerdem sollte jede Headerdatei so gut es geht eigenständig sein - In
> headerdateien möglichst nicht andere includieren.

"Leider" bleibt einem aber oft nichts anderes übrig als zig andere 
Header zu includieren um Typdefinitionen zu bekommen wie zB <stdint.h>. 
Das macht aber nichts.

Hans schrieb:
> Nehmen wir mal an ganz "normale" Header Files. Also Funktionsprototypen
> und vielleicht "extern" Variablen mit zugehörigem C-File.
Das erhöht nur die Compilezeit.

von Stefan F. (Gast)


Lesenswert?

Externe Variablen müssen irgendwo existieren. Sie belegen also entweder 
Speicherplatz oder führen zu einem Abbruch beim Linken.

Der Speicherplatz ist dann allerdings nicht im Header-File definiert, 
sondern in der "externen" Datei - das kann ja jede beliebige andere c 
oder h Datei im Projekt sein.

Gleiches gilt für Funktionen. Bei Funktionen bin ich nicht sicher, was 
passiert, wenn man eine Funktion deklariert, sie nicht verwendet und 
nicht definiert. Ich schätze, das führt ebenfalls zu einem Abbruch des 
Linkers.

Sicher bin ich allerdings, dass der Linker normalerweise alle nicht 
benutzten Funktionen entfernt. Sie existieren im compilierten programm 
gar nicht.

Manche Header Dateien definieren globale Variablen, z.B. um den Status 
von irgend etwas anzuzeigen. Diese belegen auf jeden Fall Speicher, auch 
wenn sie nicht benutzt werden. Es passiert sehr leicht, den Zugriff auf 
solche Variablen falsch zu machen, vor allem in Interruptroutinen und 
Multi-Threaded Programmen. Deswegen würde ich sowas lassen.

Wenn Du z.B. eine SD-Karten Library hast, die anzeigen soll, ob eine 
Karte eingesteckt ist und ob sie bereit ist, dann mach das nicht über 
eine von überall aus erreichbare globale Variable sondern stelle eine 
Funktion zur Verfügung, die den Wert der Variablen liefert. Nur die 
Funktion soll außerhalb der Library erreichbar sein. Das kostet zwar 
etwas Code und Performance, vermeidet aber Fehler durch Falsche 
Anwendung.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Stefan us schrieb:
> Externe Variablen müssen irgendwo existieren. Sie belegen also
> entweder
> Speicherplatz oder führen zu einem Abbruch beim Linken.
Nur wenn man sie verwendet.
> Funktionen bin ich nicht sicher, was passiert, wenn man eine Funktion
> deklariert, sie nicht verwendet und nicht definiert. Ich schätze, das
> führt ebenfalls zu einem Abbruch des Linkers.
Ja, die berühmten "undefined reference" Fehler die hier 3x täglich 
aufschlagen.
> Sicher bin ich allerdings, dass der Linker normalerweise alle nicht
> benutzten Funktionen entfernt. Sie existieren im compilierten programm
> gar nicht.
Nein. Beim GCC z.B. nur wenn man mit "-ffunction-sections" 
compiliert&linkt und mit "-Wl,--gc-sections" linkt.
> Manche Header Dateien definieren globale Variablen, z.B. um den Status
> von irgend etwas anzuzeigen. Diese belegen auf jeden Fall Speicher, auch
> wenn sie nicht benutzt werden.
Es sei denn man lässt unbenutzte Variablen mit "-fdata-sections" & 
"-Wl,--gc-sections" wegoptimierten (GCC).
Variablen in Headern zu definieren (d.h. ohne extern) ist onehin 
sinnlos, weil dann für jede .c Dateie eine eigene angelegt wird und man 
nicht auf die der anderen Dateien zugreifen kann.

von Karl H. (kbuchegg)


Lesenswert?

Dr. Sommer schrieb:
> Stefan us schrieb:
>> Externe Variablen müssen irgendwo existieren. Sie belegen also
>> entweder
>> Speicherplatz oder führen zu einem Abbruch beim Linken.
> Nur wenn man sie verwendet.
>> Funktionen bin ich nicht sicher, was passiert, wenn man eine Funktion
>> deklariert, sie nicht verwendet und nicht definiert. Ich schätze, das
>> führt ebenfalls zu einem Abbruch des Linkers.
> Ja, die berühmten "undefined reference" Fehler die hier 3x täglich
> aufschlagen.

Achtung:
Er sagte "sie nicht verwendet".
In dem Fall passiert gar nichts.


Deklarieren darf man eine Funktion so oft und so viel man will. Auch 
wenn sie nicht existiert. Solange sie nicht verwendet wird, ist das dem 
Linker piep-egal. Eine Funktionsdeklaration interessiert ja nur den 
Compiler, damit er evetuelle Aufrufe prüfen kann. Gibt es keinen Aufruf, 
interessiert die Deklaration niemanden weiter.

von Dr. Sommer (Gast)


Lesenswert?

Karl Heinz schrieb:
> Achtung:
> Er sagte "sie nicht verwendet".
> In dem Fall passiert gar nichts.
Oh. Brille putz

von Stefan F. (Gast)


Lesenswert?

@Dr. Sommer

Ich habe inzwischen mal die von Dir empfohlene Compiler (bzw Linker) 
Option "-Wl,--gc-sections" ausprobiert. Diese hat auf mein Projekt 
(Webserver) aber überhaupt keinen Einfluss, es kommt exakt das gleiche 
binary heraus.

Nun ist es so, dass meine Quelltexte keine unnötigen Funktionen 
enthalten. Insofern ist dies als das erwartete Ergebnis.

Aber eines ist mir in diesem Zusammenhang noch unklar: Ich binde einige 
Standard Libraries ein, die zahlreiche unbenutzte Funktionen enthalten. 
Sie blähen mein Binary anscheinend dennoch nicht unnötig auf.

Sehe ich es richtig, dass der Compiler/Linker unbenutzte Funktionen aus 
den Standard Libraries automatisch entfernt - auch ohne diese Option?

von Karl H. (kbuchegg)


Lesenswert?

Stefan us schrieb:

> Sehe ich es richtig, dass der Compiler/Linker unbenutzte Funktionen aus
> den Standard Libraries automatisch entfernt - auch ohne diese Option?

Anders rum.
Er holt sich nur das, was er braucht.
Was aber im Endeffekt aufs gleiche rausläuft.

Diese gcc-Linker Option brauchst du ja auch nur deswegen, weil dieser 
Linker Object-Files als ganzes einbindet, ohne sich um die Aufteilung in 
Funktionen zu kümmern. Andere Linker machen das anders.
Würdest du beim gcc-Linker von vorne herein jede Funktion in ein eigens 
C-File stecken und getrennt compilieren, hätte das daher den gleichen 
Effekt, wie diese Option.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Aah, jetzt hab ichs verstanden. Dankeschön.

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.