Est-il préférable de documenter les fonctions dans le fichier d'en-tête ou le fichier source?

86

Dans les langages qui distinguent un fichier "source" et "en-tête" (principalement C et C ++), est-il préférable de documenter les fonctions dans le fichier en-tête:

(dérobé de CCAN )

/**
 * time_now - return the current time
 *
 * Example:
 *  printf("Now is %lu seconds since epoch\n", (long)time_now().tv_sec);
 */
struct timeval time_now(void);

ou dans le fichier source?

(dérobé à PostgreSQL)

/*
 * Convert a UTF-8 character to a Unicode code point.
 * This is a one-character version of pg_utf2wchar_with_len.
 *
 * No error checks here, c must point to a long-enough string.
 */
pg_wchar
utf8_to_unicode(const unsigned char *c)
{
...

Notez que certains éléments sont définis dans l'en-tête uniquement, tels que les structures, les macros et les static inlinefonctions. Je parle seulement de choses qui sont déclarées dans un fichier d'en-tête et définies dans un fichier source.

Voici quelques arguments auxquels je peux penser. Je suis enclin à documenter dans le fichier source, mes arguments "Pro-en-tête" peuvent donc être quelque peu faibles.

Pro-header:

  • L'utilisateur n'a pas besoin du code source pour voir la documentation.
    • La source peut être difficile, voire impossible, à acquérir.
    • Cela maintient l'interface et la mise en œuvre plus éloignées.

Pro-source:

  • Cela rend l'en-tête beaucoup plus court, donnant au lecteur une vue à vol d'oiseau du module dans son ensemble.
  • Il associe la documentation d'une fonction à son implémentation, ce qui permet de voir plus facilement qu'une fonction fait ce qu'elle dit.

Lorsque vous répondez, méfiez-vous des arguments basés sur ce que peuvent faire les outils et les "IDE modernes". Exemples:

  • En-tête Pro: le pliage de code peut aider à rendre les en-têtes commentés plus navigables en masquant les commentaires.
  • Source Pro: cscope de Find this global definitionfonction vous amène au fichier source (où la définition est) plutôt que le fichier d' en- tête (où la déclaration est).

Je ne dis pas qu'il ne faut pas argumenter de la sorte, mais n'oubliez pas que tout le monde n'est pas aussi à l'aise avec les outils que vous utilisez.

Joey Adams
la source
La même question peut s'appliquer à Pascal / Delphi où nous n'avons pas de fichiers source et d'en-tête, mais des sections d'interface et d'implémentation.
Jan Doggen
1
Voir aussi stackoverflow.com/questions/355619/…
cp.engr le

Réponses:

96

Mon avis...

  • Expliquez comment utiliser la fonction dans le fichier d'en-tête ou, plus précisément, à proximité de la déclaration.

  • Documentez le fonctionnement de la fonction (si cela ne ressort pas du code) dans le fichier source, ou plus précisément, proche de la définition.

Pour la vue d'ensemble dans l'en-tête, vous n'avez pas nécessairement besoin de la documentation qui se ferme: vous pouvez documenter des groupes de déclarations à la fois.

De manière générale, l'appelant devrait s'intéresser aux erreurs et aux exceptions (si seulement elles pouvaient être traduites à mesure qu'elles se propagent à travers les couches d'abstraction) afin que celles-ci soient documentées à proximité des déclarations correspondantes.

Steve314
la source
13
+1 - c.-à-d. Documentez l'interface dans l'en-tête. Les détails de Gory du comment et du pourquoi dans la source.
Rapidement maintenant
2
Pour les en-têtes de bibliothèque où aucune source n'est disponible, ajoutez éventuellement des conditions préalables et postérieures, etc., pour faciliter les tests. De plus, ajoutez des performances O (n) si cela a du sens, afin que les utilisateurs de bibliothèques puissent choisir judicieusement.
Patrick Hughes
Naturellement, parfois, déclaration et définition ne font qu'un.
Déduplicateur
@DuDuplicator - Lorsque les mêmes règles donnent toujours raison, même dans le cas particulier, pourquoi faire écho à ces règles pour chaque cas particulier? Un déduplicateur ne devrait-il pas vouloir cela?
Steve314
1
@DuDuplicator - Bien sûr, c’est une raison assez invraisemblable de ne pas suivre votre conseil, mais je m'en tiens à cela.
Steve314
34

Si vous allez utiliser un outil tel que Doxygen (remarquez dans le premier exemple, cela ressemble vraiment à un commentaire Doxygen car il commence par /**), cela n'a pas vraiment d'importance - Doxygen examinera vos fichiers d'en-tête et source et recherchera tous les commentaires pour générer la documentation.

Cependant, je serais plus enclin à mettre les commentaires de documentation dans les en-têtes, où se trouvent les déclarations. Vos clients vont utiliser les en-têtes pour interagir avec votre logiciel. Ils vont inclure ce qu'ils vont inclure dans leurs propres fichiers source et c'est là qu'ils vont d'abord regarder pour voir à quoi ressemble votre API.

Si vous regardez la plupart des bibliothèques Linux, par exemple, votre système de gestion de paquets Linux contient souvent un paquet contenant uniquement les fichiers binaires de la bibliothèque (pour les utilisateurs "normaux" ayant des programmes nécessitant la bibliothèque) et vous avez un paquet "dev" contient les en-têtes de la bibliothèque. Le code source n'est normalement pas fourni directement dans un package. Il serait vraiment fastidieux d’obtenir le code source d’une bibliothèque quelque part pour obtenir la documentation de l’API.

Jesper
la source
2
+1 - avec la certitude que même si vous utilisez Doxygen, cela ne signifie pas que vous ne lirez jamais directement à partir de la source. Les annotations Doxygen sont même parfois utiles en tant que modèles standard à grep, et elles sont pratiques si l'annotation que vous trouvez est proche du code qu'elle décrit.
Steve314
1
@ Steve314 ofcourse Je n'ai pas dit que vous ne voudriez jamais regarder le code source d'une bibliothèque - mais ce ne serait pas le premier endroit où vous chercheriez à quoi ressemble l'API et comment l'utiliser.
Jesper
Je recommanderais également de conserver tout ce qui concerne l'API dans l'en-tête (ou du moins dans l'en-tête ou la source), car cela éviterait une incohérence potentielle lors de la mise à jour de la documentation à un endroit et non à l'autre.
Jopasserat
12

Nous avons résolu ce problème (il y a environ 25 ans) en créant un ensemble de #defines (par exemple, public, private, etc., résolus en <rien>) pouvant être utilisés dans le fichier source et analysés par un script awk (horror !) pour générer automatiquement les fichiers .h. Cela signifie que tous les commentaires résidaient dans la source et ont été copiés (le cas échéant) dans le fichier .h généré. Je sais que c'est assez Old School, mais cela simplifie grandement ce type de documentation en ligne.

Peter Rowell
la source
1
hmm je sais que ce genre de chose peut être utile, mais de mon point de vue, j'ai toujours trouvé ce genre de documentation carrément ennuyante ...
osirisgothra
1
Pour paraphraser Donald Rumsfeld (un homme que je n’ai pas aimé): "Vous programmez avec les outils que vous avez, pas avec ceux que vous souhaiteriez avoir." Toutes les langues avec lesquelles j'ai travaillé au cours des 40 dernières années ont eu au moins une verrue majeure (sinon plus). Notre solution a) fonctionnait, b) utilisait des outils qui existaient à l’époque, c) nous passions notre temps à obtenir du code générateur de revenus.
Peter Rowell
Même si je n'opterais probablement pas pour cela, c'est un moyen intéressant de gérer les commentaires dans les en-têtes. Les en-têtes générés seraient-ils dans le contrôle de version? ou s'agit-il d'un processus de publication permettant de créer une source redistribuable? (mais pas utilisé par les développeurs)
ideasman42
Oh, j'ai récemment vu le même modèle dans un projet lancé en 2000 et ils étaient si fiers de leur invention si intelligente…
5gon12eder
3
Dans notre cas, nous n’avons gardé aucun des fichiers générés sous contrôle de version car ils étaient facilement et (directement) dérivés de fichiers suivis.
Peter Rowell
9

En supposant qu'il s'agisse de code dans un projet plus important (où les développeurs vont souvent changer de source et d'en-tête) , et que ce n'est pas une bibliothèque / middleware, où d'autres n'ont peut-être pas accès à la source, j'ai trouvé que cela fonctionnait meilleur...

  • En-têtes:
    1-2 commentaires de ligne succincts, uniquement s'ils sont nécessaires.
    Parfois, les commentaires au-dessus d’un groupe de fonctions connexes sont également utiles.
  • Source:
    Documentation sur l'API directement au-dessus de la fonction (texte brut ou doxygen si vous préférez) .
  • Conservez les détails de l'implémentation, qui ne concernent qu'un développeur qui modifie le code dans le corps de la fonction.

La raison principale en est de garder les commentaires proches du code, j’ai remarqué que les docs dans les en-têtes ont tendance à se désynchroniser plus souvent avec les modifications du code (bien sûr, ils ne devraient pas, mais ils l’ont fait dans notre projet à le moins) . Les développeurs peuvent également ajouter de la documentation au sommet des fonctions lorsqu'ils apportent des modifications, même s'il existe des documents d'en-tête ... quelque part. Causer des doublons ou des informations utiles uniquement dans l'une des chaînes de documentation.

Bien sûr, vous pouvez choisir une convention et vous assurer que tous les développeurs suivent. Je viens de trouver la convention ci-dessus la plus naturelle et la moins dérangeante à maintenir.


Enfin, pour les grands projets - theres une inclinaison non de faire de petites corrections dans un en- tête quand vous savez que sa va potentiellement causer de des fichiers de ou 1000 100 recompiler quand d' autres mettent à jour le contrôle de version - ralentissement des erreurs bissectrice aussi.

idéesman42
la source
5

À mon avis (plutôt limité et partial), je suis une façon de penser du code source. Lorsque je fais des bricoles en C ++, je modifie généralement le fichier d’en-tête une fois, puis je ne le regarde jamais vraiment.

Lorsque je place la documentation dans le fichier source, je la vois toujours lorsque je modifie ou lis des codes. Je suppose que c'est une chose d'habitude.

Mais c'est juste moi ...

MattyD
la source
1
Ne fonctionne pas très bien si tout ce que vous avez est une bibliothèque compilée et le fichier d’en-tête. Dans ce cas, avoir plus d’informations dans l’en-tête est une bonne chose car c’est la seule documentation d’interface que vous avez.
Rapidement maintenant
vous pouvez générer de la documentation avec doxygen - elle l’utilise également à partir de fichiers .c. Ainsi, vous pouvez facilement distribuer la documentation avec les bibliothèques compilées. Mais le problème serait avec l'IDE qui peut analyser les fichiers d'en-tête et vous fournir de la documentation tout en utilisant la fonction ... Mais peut-être pourrait-il résoudre un script de déploiement permettant de copier les commentaires de fonction de
frm .c
5

Les commentaires ne sont pas de la documentation. La documentation d'une fonction peut généralement comporter 2 Ko de texte, éventuellement avec des diagrammes - voir, par exemple, la documentation relative aux fonctions dans le SDK de Windows. Même si votre commentaire-à-doc le permet, vous rendrez le code contenant le commentaire illisible. Si vous souhaitez produire de la documentation, utilisez un traitement de texte.

Neil Butterworth
la source
mettre à jour, il est beaucoup plus facile de documenter ces jours-ci (avec des choses comme Qt Creator) pour simplement documenter la manière doxygen (ou cloner), par exemple, dans qtc vous appuyez juste quelques fois sur la touche / avant le commentaire et la moitié du le travail est fait pour vous. À cause de choses comme celle-ci, je doute que les gens veuillent passer à un traitement de texte juste pour documenter leur code. J'avais l'habitude de faire cela, d'accord, en 2005, mais je ne le ferais jamais maintenant. Même en utilisant un éditeur HTML semble être assez archaïque maintenant.
osirisgothra
La "documentation" de @osirisgothra Doxygen- peut être facile à faire et produit certainement beaucoup de lettres de créance rapidement écrites, mais la valeur de la "documentation" produite reste discutable dans la grande majorité des cas. Les commentaires Doxygen ne sont ni une bonne documentation (presque tous les détails cruciaux sont généralement manquants), ni des bons commentaires (ils ont tendance à répéter ce qui est déjà évident de la signature). Je pense que nbt a raison de dire qu’il est préférable de ne pas mélanger la documentation réelle avec du code, car elle nuit à la lisibilité du code. De toute façon, ça va se désynchroniser, il n'y a pas de solution miracle pour ça.
cmaster
4

Si les parties prenantes de votre code source (par exemple, une petite bibliothèque) sont composées d '"utilisateurs" (collègues développeurs qui utiliseront les fonctionnalités de votre bibliothèque sans s'impliquer dans son implémentation) et de "développeurs" (vous et d'autres développeurs qui implémenteront la bibliothèque) , placez ensuite les "informations relatives aux utilisateurs" dans l'en-tête et la "note d'implémentation" dans le source.

En ce qui concerne le désir de ne pas modifier les fichiers d’en-tête plus que ce qui est absolument nécessaire - je suppose que si votre bibliothèque n’est pas "dans un flux de changements insensé", l’interface et la "fonctionnalité" ne changeront pas beaucoup, et les commentaires d'en-tête doivent-ils changer trop souvent? D'autre part, les commentaires du code source devront rester synchronisés ("frais") avec le code source.

rwong
la source
0

L’utilisation de doxygen a pour objectif essentiel de générer de la documentation et de la rendre accessible ailleurs. Désormais, toute la documentation contenue dans les en-têtes ne constitue que des déchets, ce qui rend plus difficile la détection rapide de la déclaration de fonction requise, voire de ses surcharges. Un commentaire de ligne est le maximum qui devrait y aller, mais même cela est une mauvaise pratique. Si vous modifiez la documentation dans la source, vous devez recompiler cette source et rétablir le lien. Mais si vous mettez la documentation dans l'en-tête, vous ne voulez vraiment pas changer la moindre chose, car cela va déclencher une partie importante de la reconstruction du projet.

Slava
la source
1
cela ne semble rien offrir de substantiel sur les points soulevés et expliqués dans les 7 réponses précédentes
gnat
1
@gnat sur les 7 réponses précédentes, un seul est en faveur du code contre les en-têtes. Et celui-là donne une argumentation totalement différente.
Slava