Header Dateien weglassen?



  • Gibt es große Nachteile wenn ich einfach diese ganzen Headerdateien, in meinen kleinen Ein-Mann-Projekten, weg lasse und nur mit Implementierungen arbeite?


  • Mod

    Ja. Es wird nicht funktionieren.



  • Hi Zee++,

    kommentiere sie doch mal probeweise mit //aus und erfreue Dich an den Fehlermeldungen Deines Compilers und ggf Linkers.
    Danach stellst Du die Frage so nicht mehr.

    Was anderes ist es, wenn Du Deine eigenen Headderdateien weglassen willst. Natürlich kannst Du alle Definitionen auch genau so gut direkt in der eigentlichen Quelltextdatei an den Anfang stellen. Wenn es nur die eine Datei gibt, dann ist das kein Problem. Aber dabei bleibts ja meist nicht.
    Wie sollen Programmteile aus der einen Datei wissen wie eswas in der anderen Datei steht aufgerufen werden muss. Du kannst ja nicht den ganzen Quelltext reinladen.

    Gruß Mümmel


  • Mod

    muemmel schrieb:

    Was anderes ist es, wenn Du Deine eigenen Headderdateien weglassen willst. Natürlich kannst Du alle Definitionen auch genau so gut direkt in der eigentlichen Quelltextdatei an den Anfang stellen. Wenn es nur die eine Datei gibt, dann ist das kein Problem. Aber dabei bleibts ja meist nicht.
    Wie sollen Programmteile aus der einen Datei wissen wie eswas in der anderen Datei steht aufgerufen werden muss. Du kannst ja nicht den ganzen Quelltext reinladen.

    So wie ich das verstanden habe, ist genau dies der Plan und darauf bezog sich auch meine Antwort.

    Weiterer Nachteil: Selbst wenn man es irgendwie hinbekommen sollte, lernt man nie, wie es richtig geht, und bleibt auf winzige Projekte und Frickellösungen beschränkt.



  • Es geht nur um meine eigenen Headerdateien.

    Ich will sie nicht einfach weglassen, sondern gar keine Prototypen für meine Funktionen mehr erstellen. Einfach diese doppelte Krücke loswerden.



  • Tip: informiere dich über die Aufgaben und das Zusammenspiel zwischen Präprozessor, C-Compiler und Linker. Kompiliere mal ein Multi-Dateien-Projekt von Hand auf der Kommandozeile. Dann wird klar, daß die Aufteilung in Header- und Source-Dateien eine einfache und fast schon zwangsläufige Lösung ist für das Problem, aus mehreren Source-Dateien lauffähigen Code zu machen.



  • Wieso ist das ein Problem? Ich habe mehrere .c Dateien und inkludieren die alle in eine main.c . Was nur wegfallen soll sind die .h Dateien in denen nochmal extra die Deklarationen drin stehen. Diese doppelt gemoppelt soll einfach weg. Ich will nur mit Definitionen arbeiten. Warum sollte das ein Problem sein?

    Das einzige was mir einfällt ist eine länge Kompilierungszeit, da der Compiler nur eine Datei bekommt in der immer alles drin ist(bis auf externe Libs).

    Ausprobiert habe ich das schon. Funktioniert wunderbar. Ich wollte hier nur nach eventuellen Nachteilen fragen die mir jetzt noch nicht bewusst sind.



  • Hallo Zee++,

    wenn du .c-Dateien inkludierst (was du auf keinen Fall machen solltest), statt sie separat zu kompilieren, dann sind sie eigentlich Header-Dateien, bloß mit der falschen Dateiendung. Das würde ich an deiner Stelle rasch in Ordnung bringen. 😉

    Was du beschreibst, ist eine Header-only Bibliothek; sprich, alle Definitionen sitzen im Header und es gibt keine Implementierungsdateien. Header-only Bibliotheken sind in C++ sehr beliebt, zumal es oft gar keinen anderen Weg gibt wegen den Templates. Für prominente Vertreter, siehe Boost oder Eigen.

    Ein Vorteil von Header-only Bibliotheken ist, dass der Nutzer sie einfacher einbinden kann, da er sie nicht zuvor kompilieren und danach gegen sie linken muss.
    Der primäre Nachteil ist die erhöhte Kompilationszeit. Wenn du etwas Kleines in den Definitionen (also nur in der Implementierung, nicht mal im Interface) änderst, musst du trotzdem dein gesamtes Projekt neu kompilieren. Dieser Punkt ist zugegebenermaßen zu vernachlässigen in Zeiten von 16-Thread Prozessoren und Ninja. 😉

    Für C++ (kenne die Situation bei C nicht) musst du die ODR beachten. Bei Header-only Bibliotheken musst du vor alle Funktionen inline schreiben. Die Ausnahme bilden Funktions-Templates und Member-Funktionen, denn diese sind implizit inline wenn sie gleichzeitig definiert wie deklariert werden.

    LG



  • Besten Dank für die erste sinnvolle Antwort hier.



  • Zee++ schrieb:

    Besten Dank für die erste sinnvolle Antwort hier.

    Was für eine unfaire zynische Antwort. Die Anderen haben durchaus sinnvolle Antworten geliefert, nur war deine Fragestellung nicht sinnvoll strukturiert und dein Ansatz war auch sinnfrei...



  • Zee++ schrieb:

    Wieso ist das ein Problem? [...] Diese doppelt gemoppelt soll einfach weg. Ich will nur mit Definitionen arbeiten. Warum sollte das ein Problem sein?

    weil bei separater Kompilierung mehrerer .c-Dateien der Kompiler bei Kompilierung von Datei A.c nicht weiß, was in Datei B.c steht. Der Kompiler muß aber trotzdem prüfen, daß du die in B.c definierten Funktionen in A.c in korrekter Weise aufrufst. Dazu muß der Kompiler bei Kompilierung von A.c die Signatur der Funktionen, die in Datei B.c definiert sind kennen. Und dazu braucht der Kompiler die Prototypen der in B.c definierten Funktionen schon in A.c. Da man die Prototypen nicht mehrfach schreiben will, schreibt man sie *einmal* in eine Datei B.h und schreibt in A.c (und in allen anderen .c-Dateien, wo Funktionen aus B.c aufgerufen werden): #include "B.h"

    Erst der Linker hat den Gesamt-Überblick über die Signaturen aller beteiligten Funktionen; das nützt beim Kompilieren aber nichts, denn der Linker kommt aber erst zum Einsatz, *nachdem* die verschiedenen Kompiler-Aufrufe aus den .c-Dateien Object-Code erzeugt haben.



  • Fytch schrieb:

    Dieser Punkt ist zugegebenermaßen zu vernachlässigen in Zeiten von 16-Thread Prozessoren und Ninja. 😉

    Das ist überhaupt nicht zu vernachlässigen. Die Buildzeit ist nach wie vor ein Riesenproblem. Dein Projekt muss nur groß genug sein.



  • Ich habe hier aber von kleinen Ein-Mann-Projekten geredet.



  • zufallswert schrieb:

    Zee++ schrieb:

    Wieso ist das ein Problem? [...] Diese doppelt gemoppelt soll einfach weg. Ich will nur mit Definitionen arbeiten. Warum sollte das ein Problem sein?

    weil bei separater Kompilierung mehrerer .c-Dateien

    Die seperaten .c Dateien werden aber alle in main.c inlkudiert und sollte, wie hier auch schon vorgeschlagen, dann ein .h umbenannt werden. Der Kompiler bekommt also sehrwohl den gesamten Code auf einmal zu Gesicht und kann bestimmt dadurch sehr gut optimieren.



  • wenn alles in einer einzigen compilation unit steht, muß nach funktionalen Änderungen an irgendeiner der .c-Dateien der gesamte Quellcode neu kompiliert werden. Das kann bei großen Projekten Stunden dauern. Inkrementelle Kompilierung ade.



  • Ob ich bei meinen Ein-Mann-Projekten, um die es hier geht, einen kompletten Rebuild mache oder nur die Dateien kompilieren lassen die Änderungen erfahren haben, macht hier auf dem i7 keinerlei merkbaren zeitlichen Unterschied.

    Ich denke wir können das Thema abharken. Es gibt für kleine Projekte keinen Nachteil wenn man Deklaration und Implementieren zusammenfasst und alles in eine einzelne Datei inkludiert.

    Ich kann mir also das doppelte Gefrickel sparen und habe nur die Hälfte an Dateien.


  • Mod

    Zee++ schrieb:

    Ich denke wir können das Thema abharken. Es gibt für kleine Projekte keinen Nachteil wenn man Deklaration und Implementieren zusammenfasst und alles in eine einzelne Datei inkludiert.

    Doch, es gibt gewaltige Nachteile. Du wolltest diese Antwort bloß nicht hören und die andere Antwort, die du gelobt hast, hast du leider nicht richtig verstanden. Lies den Thread am besten noch einmal in Ruhe und denk über das geschriebene nach und fühl dich nicht gleich persönlich angegriffen, wenn dir jemand erklärt, warum deine Schnappsideen nicht funktionieren werden.



  • Meine Schnapssidee funktioniert doch schon. Der Präprozessor macht aus meinen ganzen .c (die besser .h heißen sollten, aber die Implementierung enthalten wie bei header libs) einen einzige Datei und dann geht alles seinen normalen weg, wie bei einem "hello world" main.c

    Ich glaube hier hat nur einer verstanden worum es überhaupt geht. Ich habe es sicherlich auch falsch erklärt. Ich will in diesem Sinne keine Headerdateien weglassen, sondern die Implementierung immer komplett in den Headerdateien drin haben. Aber wie ich die Dateien dann nenne ist doch eigentlich total egal. Inkludieren ist doch nicht anderes als Cut & Paste.



  • Depp. Noob.



  • Thema kann jetzt nun wirklich geschlossen werden. Das was ich suchte gibt es schon und zwar in Headeronly Bibliotheken.

    Danke nochmals an Fytch der als einziger den Durchblick hier hatte.


Log in to reply