Par exemple, l' outil SysInternals "FileMon" du passé possède un pilote en mode noyau dont le code source est entièrement dans un fichier de 4 000 lignes. Même chose pour le tout premier programme ping jamais écrit (~ 2 000 LOC).
Par exemple, l' outil SysInternals "FileMon" du passé possède un pilote en mode noyau dont le code source est entièrement dans un fichier de 4 000 lignes. Même chose pour le tout premier programme ping jamais écrit (~ 2 000 LOC).
Réponses:
L'utilisation de plusieurs fichiers nécessite toujours des frais administratifs supplémentaires. Il faut configurer un script de construction et / ou un fichier de compilation avec des étapes de compilation et de liaison distinctes, s'assurer que les dépendances entre les différents fichiers sont correctement gérées, écrire un script "zip" pour faciliter la distribution du code source par courrier électronique ou par téléchargement, etc. sur. Les IDE modernes actuels supportent généralement une grande partie de ce fardeau, mais je suis assez certain qu'au moment où le premier programme ping a été écrit, aucun tel IDE n'était disponible. Et pour des fichiers aussi petits que ~ 4000 LOC, sans un tel IDE qui gère plusieurs fichiers pour vous, le compromis entre la surcharge mentionnée et les avantages liés à l'utilisation de plusieurs fichiers peut permettre aux utilisateurs de prendre une décision en ce qui concerne l'approche de fichier unique.
Parce que C n’est pas bon en modularisation. Cela devient désordonné (fichiers d'en-tête et #includes, fonctions externes, erreurs de temps de lien, etc.) et plus vous apportez de modules, plus cela devient délicat.
Les langues plus modernes offrent de meilleures capacités de modularisation, en partie parce qu'elles ont été apprises des erreurs de C et facilitent la décomposition de votre base de code en unités plus petites et plus simples. Mais avec C, il peut être avantageux d’éviter ou de minimiser tous ces problèmes, même si cela signifie que l’on regrouperait ce qui serait autrement considéré comme trop de code dans un seul fichier.
Outre les raisons historiques, il y a une raison pour l'utiliser dans les logiciels modernes sensibles aux performances. Lorsque tout le code est dans une unité de compilation, le compilateur est capable d’optimiser l’ensemble du programme. Avec des unités de compilation séparées, le compilateur ne peut pas optimiser le programme entier de certaines manières (par exemple, l’inclusion de certains codes).
L'éditeur de liens peut certainement effectuer certaines optimisations en plus de ce que le compilateur peut faire, mais pas tous. Par exemple: les lieurs modernes sont très efficaces pour élire des fonctions non référencées, même à travers plusieurs fichiers objets. Ils pourront peut-être effectuer d'autres optimisations, mais rien ne ressemble à ce qu'un compilateur peut faire dans une fonction.
SQLite est un exemple bien connu de module de code à source unique. Vous pouvez en savoir plus à ce sujet sur la page de fusion de SQLite .
1. Résumé
Plus de 100 fichiers sources distincts sont concaténés dans un seul fichier volumineux de code C nommé "sqlite3.c" et appelé "la fusion". La fusion contient tout ce dont une application a besoin pour intégrer SQLite. Le fichier de fusion comprend plus de 180 000 lignes et plus de 6 mégaoctets.
La combinaison de tout le code pour SQLite dans un seul fichier de grande taille simplifie le déploiement de SQLite - il n’ya qu’un seul fichier à suivre. Et comme tout le code est dans une seule unité de traduction, les compilateurs peuvent optimiser l'optimisation entre procédures, ce qui permet d'obtenir un code machine plus rapide de 5% à 10%.
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
que de tout transférer dans un seul fichier soudce. Vous pouvez même faire la compilation complète du programme en tant que cible alternative au script de construction traditionnel qui ignore la recompilation des fichiers source qui n'ont pas été modifiés, de la même manière que les utilisateurs pourraient désactiver le profilage et le débogage pour la cible de production. Vous n'avez pas cette option si tout est dans un gros tas o'source. Ce n’est pas ce à quoi les gens sont habitués, mais cela n’a rien de lourd.
En plus du facteur de simplicité mentionné par l'autre répondant, de nombreux programmes C sont écrits par une seule personne.
Lorsque vous avez une équipe de personnes, il devient souhaitable de diviser l'application en plusieurs fichiers source pour éviter les conflits gratuits lors des modifications de code. Surtout quand il y a des programmeurs avancés et très juniors travaillant sur le projet.
Quand une personne travaille seule, ce n'est pas un problème.
Personnellement, j'utilise plusieurs fichiers basés sur la fonction comme une chose habituelle. Mais c'est juste moi.
Parce que C89 n'avait pas de inline
fonctions. Ce qui signifiait que la fragmentation de votre fichier en fonctions entraînait la surcharge de transmettre des valeurs sur la pile et de sauter. Cela a ajouté un peu de temps supplémentaire à la mise en œuvre du code dans une seule instruction de commutateur de grande taille (boucle d'événement). Mais une boucle d'événement est toujours beaucoup plus difficile à mettre en œuvre efficacement (ou même correctement) qu'une solution plus modulaire. Donc, pour les projets de grande taille, les gens choisiraient toujours de ne pas moduler. Mais quand ils ont eu la conception de la conception à l'avance et peuvent contrôler l'état dans une déclaration de commutateur, ils ont opté pour cela.
De nos jours, même en C, il n'est pas nécessaire de sacrifier les performances pour la modularisation, car même en C, les fonctions peuvent être intégrées.
inline
mot-clé dans les compilateurs C89, les compilateurs ne pouvaient pas s'inscrire en ligne, c'est pourquoi il fallait tout écrire dans une fonction géante, ce qui est incorrect. Vous ne devriez pratiquement jamais utiliser inline
comme optimisation des performances - le compilateur en sait généralement mieux que vous de toute façon (et peut tout aussi bien ignorer le mot clé).
inline
mot-clé contient une sémantique liée à l'éditeur de liens qui est plus importante que la question de savoir s'il faut ou non effectuer des optimisations en ligne, mais certaines implémentations ont d'autres directives pour contrôler l'entrée en ligne et de telles choses peuvent parfois être très importantes. Dans certains cas, une fonction peut sembler trop volumineuse pour valoir la peine d'être doublée, mais un pliage constant peut réduire la taille et le temps d'exécution à presque rien. Un compilateur qui ne reçoit pas un fort coup de pouce pour encourager l'
Cela compte comme un exemple d'évolution, ce qui, je suis surpris, n'a pas encore été mentionné.
Dans les jours sombres de la programmation, la compilation d'un seul fichier peut prendre quelques minutes. Si un programme était modularisé, l’inclusion des fichiers d’en-tête nécessaires (aucune option d’en-tête précompilée) serait une cause supplémentaire importante de ralentissement. De plus, le compilateur peut choisir / avoir besoin de conserver certaines informations sur le disque lui-même, probablement sans l'avantage d'un fichier d'échange automatique.
Les habitudes auxquelles ces facteurs environnementaux ont conduit se sont répercutées sur les pratiques de développement en cours et ne se sont que lentement adaptées au fil du temps.
À l’époque, le gain découlant de l’utilisation d’un seul fichier serait semblable à celui obtenu par l’utilisation de disques SSD au lieu de disques durs.