È meglio documentare le funzioni nel file di intestazione o nel file sorgente?

78

Nelle lingue che distinguono tra un file "sorgente" e "header" (principalmente C e C ++), è meglio documentare le funzioni nel file di intestazione:

(rubato da 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);

o nel file sorgente?

(rubged da 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)
{
...

Nota che alcune cose sono definite solo nell'intestazione, come structs, macros e static inline functions. Sto solo parlando di elementi dichiarati in un file di intestazione e definiti in un file sorgente.

Ecco alcuni argomenti a cui posso pensare. Sono incline a documentare nel file sorgente, quindi i miei argomenti "Pro-header" potrebbero essere un po 'deboli.

Pro-intestazione:

  • L'utente non ha bisogno del codice sorgente per vedere la documentazione.
    • La fonte potrebbe essere inopportuna o addirittura impossibile da acquisire.
    • Ciò mantiene l'interfaccia e l'implementazione più distanti.

Pro-source:

  • Rende l'intestazione molto più breve, dando al lettore una visione d'insieme del modulo nel suo insieme.
  • Associa la documentazione di una funzione alla sua implementazione, rendendo più facile vedere che una funzione fa quello che dice di fare.

Quando rispondi, fai attenzione agli argomenti basati su quali strumenti e "IDE moderni" possono fare. Esempi:

  • Intestazione pro: la piegatura del codice può contribuire a rendere più navigabili le intestazioni commentate nascondendo i commenti.
  • Pro-source: la funzione di cscope Find this global definition ti porta al file sorgente (dove la definizione è) piuttosto che il file di intestazione (dove la dichiarazione è).

Non sto dicendo di non formulare argomenti del genere, ma ricorda che non tutti sono a proprio agio con gli strumenti che utilizzi come sei.

    
posta Joey Adams 15.06.2011 - 06:15
fonte

8 risposte

92

La mia vista ...

  • Documenta come utilizzare la funzione nel file di intestazione, o più precisamente vicino alla dichiarazione.

  • Documenta come funziona la funzione (se non è ovvia dal codice) nel file sorgente o, più precisamente, vicino alla definizione.

Per quanto riguarda l'occhio dell'uccello nell'intestazione, non hai necessariamente bisogno della documentazione che si chiude - puoi documentare gruppi di dichiarazioni contemporaneamente.

In generale, il chiamante dovrebbe essere interessato agli errori e alle eccezioni (se solo così possono essere tradotti mentre propagano attraverso gli strati di astrazione), quindi questi dovrebbero essere documentati vicino alle dichiarazioni pertinenti.

    
risposta data 15.06.2011 - 07:15
fonte
31

Se hai intenzione di utilizzare uno strumento come Doxygen (nota nel primo esempio, sembra davvero un commento di Doxygen perché inizia con /** ), quindi non importa - Doxygen controllerà l'intestazione e i file di origine e troverà tutti i commenti per generare la documentazione.

Tuttavia, sarei più propenso a inserire i commenti della documentazione nelle intestazioni, dove si trovano le dichiarazioni. I tuoi clienti avranno a che fare con le intestazioni per interfacciarsi con il tuo software, le intestazioni sono ciò che includeranno nei loro file sorgente e sarà lì che cercheranno prima di vedere come appare la tua API.

Se guardi la maggior parte delle librerie di Linux, ad esempio, il tuo sistema di gestione dei pacchetti Linux ha spesso un pacchetto che contiene solo i binari della libreria (per utenti "normali" che hanno programmi che hanno bisogno della libreria) e hai un "dev "pacchetto che contiene le intestazioni per la libreria. Il codice sorgente non viene normalmente fornito direttamente in un pacchetto. Sarebbe davvero ingombrante se dovessi ottenere il codice sorgente di una libreria da qualche parte per ottenere la documentazione dell'API.

    
risposta data 15.06.2011 - 09:26
fonte
11

Abbiamo risolto questo problema (circa 25 anni fa) creando un sacco di #defines (ad esempio, pubblico, privato, ecc. risolti in < niente >) che potrebbero essere utilizzati nel file di origine e sono stati scansionati da un awk script (horrors!) per generare automaticamente i file .h. Ciò significa che tutti i commenti sono vissuti nell'origine e sono stati copiati (se necessario) nel file .h generato. So che è piuttosto vecchia scuola, ma ha notevolmente semplificato questo tipo di documentazione inline.

    
risposta data 15.06.2011 - 06:31
fonte
5

Nella mia opinione (piuttosto limitata e parziale), sono un modo di pensare del codice pro-sorgente. Quando eseguo bit e parti in C ++, di solito modifico il file di intestazione una volta e poi non ritorno mai veramente a guardarlo.

Quando inserisco la documentazione nel file sorgente, la vedo sempre quando sto modificando o leggendo i codici. Immagino sia una cosa abitudinaria.

Ma sono solo io ...

    
risposta data 15.06.2011 - 06:21
fonte
5

I commenti non sono documentazione. La documentazione di una funzione può essere in genere di 2K di testo, possibilmente con diagrammi: vedere ad esempio la documentazione per le funzioni nell'SDK di Windows. Anche se il tuo comment-to-doc ti consente una cosa del genere, creerai il codice che contiene il commento illeggibile. Se vuoi produrre documentazione, usa un word processor.

    
risposta data 15.06.2011 - 08:56
fonte
5

Supponendo che si tratti di codice all'interno di un progetto più grande (dove gli sviluppatori si spostano spesso tra sorgente e intestazioni) e a condizione che non sia una libreria / middleware, in cui altri potrebbero non avere accesso alla fonte, ho trovato che funziona meglio ...

  • Intestazioni:
    Tetra 1-2 commenti di riga, solo se sono necessari.
    Qualche volta anche i commenti sopra un gruppo di funzioni correlate.
  • Fonte:
    Documentazione su API direttamente sopra la funzione (testo normale o doxygen se preferisci) .
  • Mantieni i dettagli di implementazione, pertinenti solo per uno sviluppatore che modifica il codice nel corpo della funzione.

Il motivo principale per questo è di mantenere i commenti vicino al codice, ho notato che i doc nelle intestazioni tendono a non sincronizzarsi con le modifiche al codice più spesso (ovviamente non dovrebbero, ma hanno fatto almeno nel nostro progetto) . Inoltre, gli sviluppatori possono aggiungere documentazione nella parte superiore delle funzioni quando apportano alcune modifiche, anche se sono presenti documenti di intestazione ... da qualche altra parte. Causando doppi-up o informazioni utili solo per essere in una delle stringhe doc.

Ovviamente puoi scegliere una convenzione e assicurarti che tutti gli sviluppatori seguano, ho appena trovato la convenzione sopra la maggior parte natural-fit e causa meno problemi da mantenere.

Infine, per i progetti di grandi dimensioni - c'è una inclinazione non a fare piccole correzioni in un'intestazione quando si sa che causerà la ricompilazione di potenzialmente 100 o 1000 di file quando altri aggiorneranno la versione controllo - rallentando anche gli errori di bisecatura.

    
risposta data 12.10.2015 - 15:15
fonte
4

Se gli stakeholder del tuo codice sorgente (ad esempio una piccola libreria) sono "utenti" (colleghi sviluppatori che useranno le funzionalità della tua libreria senza essere coinvolti nella sua implementazione) e "sviluppatori" (tu e altri sviluppatori che implementeranno la libreria), quindi inserire le "informazioni utente" nell'intestazione e la "nota di implementazione" nella sorgente.

Per quanto riguarda il desiderio di non modificare i file di intestazione più di quanto sia assolutamente necessario - suppongo che la tua libreria non sia "in un folle flusso di cambiamenti", che "l'interfaccia" e la "funzionalità" non cambieranno molto e nemmeno i commenti dell'intestazione dovrebbero cambiare troppo frequentemente. D'altra parte, i commenti del codice sorgente dovranno essere mantenuti sincronizzati ("freschi") con il codice sorgente.

    
risposta data 15.06.2011 - 06:33
fonte
1

L'intero punto di utilizzo di doxygen è che tu generi documentazione e rendilo accessibile da qualche altra parte. Ora tutta la documentazione nelle intestazioni è solo spazzatura che rende più difficile individuare rapidamente la dichiarazione delle funciton richiesta, e forse i suoi sovraccarichi. Un commento di copertina è il massimo che dovrebbe andare lì, ma anche quello è una cattiva pratica. Causa se si modifica la documentazione nell'origine, si ricompila tale origine e si ricollega. Ma se metti i documenti nell'intestazione non vuoi davvero cambiare nulla, perché farà innescare una parte significativa della ricostruzione del progetto.

    
risposta data 05.07.2017 - 11:25
fonte

Leggi altre domande sui tag