Die Verwendung mehrerer Dateien erfordert immer zusätzlichen Verwaltungsaufwand. Man muss ein Build-Skript und / oder ein Makefile mit getrennten Kompilierungs- und Verknüpfungsstufen einrichten, sicherstellen, dass die Abhängigkeiten zwischen den verschiedenen Dateien korrekt verwaltet werden, ein "zip" -Skript schreiben, um den Quellcode einfacher per E-Mail oder Download zu verteilen und so weiter auf. Moderne IDEs sind heutzutage in der Regel sehr belastend, aber ich bin mir ziemlich sicher, dass zu dem Zeitpunkt, als das erste Ping-Programm geschrieben wurde, keine solche IDE verfügbar war. Und für Dateien , die kleiner als ~ 4000 LOC, ohne eine solche IDE , die gut für Sie mehrere Dateien verwaltet, weg von der Handel zwischen der Kopf erwähnt und die Vorteile von mehreren Dateien mit möglicherweise damit die Menschen eine Entscheidung für die einzelne Datei Ansatz machen.
Weil C keine gute Modularisierung kann. Es wird chaotisch (Header-Dateien und #includes, externe Funktionen, Verbindungsfehler usw.) und je mehr Module Sie einbinden, desto kniffliger wird es.
Modernere Sprachen haben zum Teil bessere Modularisierungsfähigkeiten, weil sie aus den Fehlern von C gelernt haben und es einfacher machen, Ihre Codebasis in kleinere, einfachere Einheiten aufzuteilen. Mit C kann es jedoch von Vorteil sein, all diese Probleme zu vermeiden oder zu minimieren, auch wenn dies bedeutet, dass zu viel Code in einer einzigen Datei zusammengefasst wird.
quelle
Abgesehen von den historischen Gründen gibt es einen Grund, dies in moderner leistungssensitiver Software zu verwenden. Befindet sich der gesamte Code in einer Kompilierungseinheit, kann der Compiler programmübergreifende Optimierungen durchführen. Bei separaten Kompilierungseinheiten kann der Compiler das gesamte Programm nicht auf bestimmte Weise optimieren (z. B. Inlining bestimmter Codes).
Der Linker kann zwar einige Optimierungen zusätzlich zu den Funktionen des Compilers durchführen, jedoch nicht alle. Zum Beispiel: Moderne Linker sind wirklich gut darin, nicht referenzierte Funktionen auch über mehrere Objektdateien hinweg zu eliminieren. Sie sind möglicherweise in der Lage, einige andere Optimierungen durchzuführen, haben jedoch nichts mit dem zu tun, was ein Compiler in einer Funktion tun kann.
Ein bekanntes Beispiel für ein Single-Source-Code-Modul ist SQLite. Weitere Informationen finden Sie auf der Seite SQLite Amalgamation .
quelle
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
als alles in eine einzige Soudce-Datei zu verschieben. Sie können sogar die Kompilierung des gesamten Programms als alternatives Ziel für das herkömmliche Erstellungsskript ausführen, bei dem das Neukompilieren von Quelldateien, die sich nicht geändert haben, übersprungen wird, ähnlich wie beim Deaktivieren der Profilerstellung und des Debuggens für das Produktionsziel. Sie haben diese Option nicht, wenn sich alles in einem großen Haufen befindet. Es ist nicht das, was die Leute gewohnt sind, aber es ist nicht umständlich.Zusätzlich zu dem von dem anderen Befragten erwähnten Einfachheitsfaktor werden viele C-Programme von einer Person geschrieben.
Wenn Sie ein Team von Einzelpersonen haben, ist es wünschenswert, die Anwendung auf mehrere Quelldateien aufzuteilen, um unbegründete Konflikte bei Codeänderungen zu vermeiden. Vor allem, wenn sowohl fortgeschrittene als auch sehr junge Programmierer an dem Projekt arbeiten.
Wenn eine Person alleine arbeitet, ist das kein Problem.
Persönlich verwende ich mehrere Dateien basierend auf der Funktion als eine gewohnheitsmäßige Sache. Aber das bin nur ich.
quelle
Weil C89 keine
inline
Funktionen hatte. Was bedeutete, dass das Aufteilen Ihrer Datei in Funktionen den Overhead verursachte, Werte auf den Stapel zu schieben und herumzuspringen. Dies führte zu einem erheblichen Mehraufwand bei der Implementierung des Codes in einer großen switch-Anweisung (Ereignisschleife). Es ist jedoch immer viel schwieriger, eine Ereignisschleife effizient (oder sogar korrekt) zu implementieren als eine modularere Lösung. Bei großen Projekten würden sich die Leute also immer noch gegen eine Modularisierung entscheiden. Aber als sie das Design im Voraus durchdacht hatten und den Status in einer switch-Anweisung steuern konnten, entschieden sie sich dafür.Heutzutage muss man auch in C nicht auf Leistung verzichten, um zu modularisieren, da sogar in C Funktionen integriert werden können.
quelle
inline
Schlüsselwort in C89-Compilern gibt, das nicht inline funktionieren könnte, weshalb Sie alles in einer riesigen Funktion schreiben mussten, falsch ist. Sie sollten es so gut wie nieinline
als Leistungsoptimierung verwenden - der Compiler weiß es im Allgemeinen sowieso besser als Sie (und kann das Schlüsselwort genauso gut ignorieren).inline
Schlüsselwort hat eine Linker-bezogene Semantik, die wichtiger ist als die Frage, ob Inline-Optimierungen durchgeführt werden sollen oder nicht. Einige Implementierungen enthalten jedoch andere Anweisungen zur Steuerung des Inlinings, und solche Dinge können manchmal sehr wichtig sein. In einigen Fällen sieht eine Funktion möglicherweise so aus, als wäre sie zu groß, als dass sie ausgekleidet werden könnte. Durch ständiges Falzen können Größe und Ausführungszeit jedoch auf fast nichts reduziert werden. Ein Compiler, der keinen starken Anstoß erhält, um dasDies gilt als Beispiel für die Evolution, von der ich überrascht bin, dass sie noch nicht erwähnt wurde.
In den dunklen Tagen des Programmierens kann das Kompilieren einer einzelnen DATEI einige Minuten dauern. Wenn ein Programm modularisiert würde, wäre die Einbeziehung der erforderlichen Header-Dateien (keine vorkompilierten Header-Optionen) eine wesentliche zusätzliche Ursache für die Verlangsamung. Zusätzlich kann es sein, dass der Compiler einige Informationen auf der Festplatte selbst speichern muss, möglicherweise ohne den Vorteil einer automatischen Auslagerungsdatei.
Die Gewohnheiten, zu denen diese Umweltfaktoren führten, wurden in die laufenden Entwicklungspraktiken übernommen und haben sich im Laufe der Zeit nur langsam angepasst.
Zu diesem Zeitpunkt wäre der Gewinn durch die Verwendung einer einzelnen Datei ähnlich wie bei der Verwendung von SSDs anstelle von HDDs.
quelle