Quali sono esempi di commenti che ti dicono perché invece di come o cosa? [chiuso]


78

Prima di tutto, in questa domanda vorrei stare lontano dalla polemica sul fatto che commentare il codice sorgente sia positivo o negativo. Sto solo cercando di capire più chiaramente cosa intendono le persone quando parlano di commenti che ti dicono PERCHÉ, COSA o COME.

Spesso vediamo linee guida come "I commenti dovrebbero dirti PERCHÉ; il codice stesso dovrebbe dirti COME". È facile concordare con l'affermazione a livello astratto. Tuttavia, la gente di solito lascia cadere questo come un dogma e lascia la stanza senza ulteriori spiegazioni. Ho visto questo usato in così tanti luoghi e contesti diversi, che sembra che le persone possano concordare sul tormentone, ma sembrano parlare interamente di cose diverse.

Quindi, tornando alla domanda: se i commenti dovessero dirti PERCHÉ, di cosa stiamo parlando? È questo il motivo per cui quel pezzo di codice esiste in primo luogo? È questo che dovrebbe fare quel codice pezzo? Gradirei davvero se qualcuno potesse dare una spiegazione chiara, e quindi aggiungere alcuni buoni esempi (esempi cattivi non sono realmente necessari, ma sono liberi di aggiungerli per contrasto).

Ci sono molte domande se i commenti sono buoni o cattivi, ma nessuno che affronta la domanda specifica di quali sono buoni esempi di commenti che ti dicono PERCHÉ.


36
A volte i migliori commenti riguardano WHY NOT. Una volta ho incontrato un po 'di codice complesso che sembrava che potesse essere facilmente semplificato. Il commento ha spiegato perché questa ovvia semplificazione non ha funzionato in questa particolare istanza (perché lo sviluppatore originale l'ha già provata).
Dan Pichelman,

6
There are many questions on whether comments are good or bad, but no one that addresses the specific question of what are good examples of comments that tell you WHY. Se tutti forniscono un esempio valido, allora sono tutte risposte corrette. Il formato di questo sito Web è di facilitare un processo di domande e risposte in cui non tutte le risposte sono uguali.
David Kaczynski,

Buon punto, @ david-kaczynski. Che cosa suggerisci?
rick

1
In cima alla mia testa, non riesco a pensare a un modo per formulare la domanda in modo che un singolo esempio o tattica generalizzata possa essere la risposta "migliore". C'è una parte di chat di p.se: chat.stackexchange.com/rooms/21/the-whiteboard , ma probabilmente ci sarebbe un forum migliore là fuori per la tua domanda così com'è. In tutta onestà, sembra che la tua domanda stia ricevendo una risposta positiva dalla comunità qui, quindi probabilmente non vale la pena preoccuparsi. Il miglior consiglio che posso dare per trovare esempi di commenti utili sarebbe quello di sfogliare i popolari repository Git pubblici.
David Kaczynski,

Risposte:


62

L'esempio più comune e più distintivo sono i commenti intorno a varie soluzioni alternative. Ad esempio questo:

https://github.com/git/git/blob/master/compat/fopen.c :

/*
 *  The order of the following two lines is important.
 *
 *  FREAD_READS_DIRECTORIES is undefined before including git-compat-util.h
 *  to avoid the redefinition of fopen within git-compat-util.h. This is
 *  necessary since fopen is a macro on some platforms which may be set
 *  based on compiler options. For example, on AIX fopen is set to fopen64
 *  when _LARGE_FILES is defined. The previous technique of merely undefining
 *  fopen after including git-compat-util.h is inadequate in this case.
 */
#undef FREAD_READS_DIRECTORIES
#include "../git-compat-util.h"

Troverai sicuramente altri esempi nelle fonti Git e Linux; entrambi i progetti cercano di seguire questa regola.

Consiglio anche di seguire questa regola ancora più rigorosamente con i log di commit . Per i commenti sul codice può accadere che tu aggiusti il ​​codice, ma dimentica di aggiornare il commento. Con la quantità di codice nel normale progetto, è garantito che accada prima o poi. D'altro canto, il registro di commit è legato alla particolare modifica e può essere richiamato utilizzando la funzionalità "annota" / "biasima" del sistema di controllo della versione. Ancora una volta Git e Linux hanno dei buoni esempi.

Guarda ad esempio questo commit . (non copiare qui, è troppo lungo). Ha quattro paragrafi che occupano quasi l'intera pagina (e un po 'più di uno schermo) che descrivono cosa era esattamente sbagliato e perché era sbagliato e poi va avanti e modifica tutte le linee SIX frustate. Usano commenti come questo per due scopi:

  1. Tutte le modifiche inviate vengono esaminate e il registro di commit è ciò che deve spiegare la modifica al revisore.
  2. Quando viene rilevato un bug, i log pertinenti vengono recuperati utilizzando "piccone" o "colpa" per evitare di tornare a comportamenti precedenti anche errati.

(nota: mi ci sono voluti al massimo 10 minuti di navigazione casuale del repository git per trovare questi due esempi, quindi sarebbe facile trovarne di più lì)


29

Un commento che spiega perché spiega il ragionamento alla base del codice, ad esempio:

// We need to sync the values if the temp <doodad> GUID matches one of the active <doodad>'s
// GUID, as the temp <doodad> has the most recent values according to the server and said 
// values might have changed since we added the <doodad>. We want a user to be able to <foo> 
// the <doodad> whenever, which means those values must be accurate.
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

Un commento che spiega come spiega cosa fa il codice.

// Loop through our <doodads> and check for a GUID match. If it matches, copy the new values
// on the <doodad> that matches 
for (doodad in doodads) {
    if ([doodad guid] == [tempDoodad guid]) {
        [doodad updateFromDoodad:tempDoodad];
        break;
    }
}

La differenza è che un manutentore può guardare il primo e dire "Oh, quindi potrebbe non essere aggiornato!" Nel secondo caso, detto manutentore ha un commento che non ti dice nulla che il codice stesso non rivela (assumendo buoni nomi di variabili).

Ecco un esempio reale di un commento sul perché, da un codice iOS su cui ho lavorato dove avevamo bisogno di ottenere un indirizzo gateway (o ipotesi ragionevole per questo). Avrei potuto semplicemente lasciare i commenti che dicevano cose come "Inizializza il socket di ricezione", ma ciò avrebbe solo detto a un manutentore (o futuro me) cosa stava succedendo, non perché avrei dovuto fare questo strano kludge per ottenere l'indirizzo del gateway nel primo posto.

/*
 We're going to do something really hacky here and use a custom partial
 implementation of traceroute to get our gateway IP address.

 [rant removed - irrelevant to the point]

 There's no good way to get at the gateway address of an iDevice
 right now. So, we have two options (per https://devforums.apple.com/message/644915#644915 ):
 1. Get at and parse the routing table (like netstat -rn, or route -n)
 2. Do a traceroute and grab the IP address for the first hop

 As far as I can tell, the former requires <sys/route.h> from the Mac OS X
 header files, which doesn't seem like a good idea to me. Also, there's a
 thread on the Apple Developer forums that seems to imply that header isn't
 in iOS for a reason (https://devforums.apple.com/message/774731#774731 ).

 So when we send our request with a TTL of one it will survive a single hop
 to the router and return, triumphant, with the router's IP address!

 Viva la kludge!

 PS: Original source was the below SO question, but I've modded it since then.
 http://stackoverflow.com/questions/14304581/hops-tracing-ttl-reciveform-on-ios/14304923#14304923
 */

// Default to using Google's DNS address. We used to try checking www.google.com
// if reachability reported we had internet, but that could still hang on routers
// that had no internet connectivity - not sure why.
const char *ip_addr = [kGoogleDNS UTF8String]; // Must be const to avoid undefined behavior
struct sockaddr_in destination,fromAddr;
int recv_sock;
int send_sock;

// ... more code follows

4
Il primo esempio è eccessivamente dettagliato e include gran parte del "come". Dovrebbe dire solo "Aggiorna <doodads> da temp <doodad> in modo che l'utente possa tranquillamente <foo> farlo ogni volta." Il resto è banale da implicare da questo o dal codice. Anche l '"introduzione delle fiabe" nei primi quattro paragrafi dell'ultimo esempio è totalmente inutile. Lascerei "Viva la kludge!"; è divertente ed è alla fine. Ma l'inizio sono troppe parole che uno deve scavare prima di arrivare alla spiegazione effettiva.
Jan Hudec,

@JanHudec Modificato secondo il tuo feedback. Guarda bene?
thegrinner,

15
Una delle cose belle del secondo esempio è che non solo spiega perché il codice funziona in un modo particolare, ma spiega anche perché non sono state prese altre alternative ragionevoli. Questo rende il codice molto più gestibile, dal momento che il prossimo che legge il codice e pensa "Perché non posso semplicemente analizzare la tabella di routing?" posso solo leggere il commento. Inoltre, qualcuno che trova un motivo legittimo per cambiare il codice sarà più sicuro che sia sicuro farlo. Altrimenti, un manutentore ha paura che qualsiasi cambiamento fallisca nello scenario (sconosciuto) che ha ispirato il kludge.
Brian,

18

Vorrei iniziare la mia risposta con una citazione fatta da Jeff Atwood nel suo post sul blog Il codice ti dice come, i commenti ti dicono perché :

il miglior tipo di commenti sono quelli che non ti servono

Dichiara inoltre che:

Dovresti prima cercare di rendere il tuo codice il più semplice possibile da capire senza fare affidamento sui commenti come una stampella. Solo nel punto in cui non è possibile semplificare la comprensione del codice, è possibile iniziare ad aggiungere commenti.

Sono totalmente d'accordo e a questo punto devo aggiungere che prima di poter iniziare a rendere il codice il più semplice possibile, faccio funzionare il codice e quindi inizio il refactoring. Quindi durante la prima esecuzione prima del refactoring aggiungendo perché i commenti aiutano molto.

Ad esempio, se si utilizzano 3 loop nidificati con hashtable bidimensionali per riempire una tabella di giorni della settimana durante l'analisi dei dati, è molto facile perdere traccia di ciò che è stato fatto da qualcuno o anche se stessi se non guardati per alcune settimane e improvvisamente refactoring.

[loop1]6oclock -> [loop2]Monday -> [loop3]stage 1 to 4
         -> tuesday-> stage 1 to 4
         ...
         -> Saturday -> stage 1 to 4
    7oclock -> Monday-> stage 1 to 4
        ....etc.

Il superiore è un esempio di come funzionerebbero 3 loop nidificati prima del refactoring.
Spiegare anche alcune condizioni del ramo può aiutare a capire molto meglio il codice con ciò che si pensava nel processo:

// added a zero before the actual day in order for the days always to be 2 digits long.
if( actualDayFuture < 10 ) 
{ 
     actualDayFuture = padIfSingleDigitDate(actualDayFuture); 
}

Anche il codice semplice e ovvio funziona bene con i commenti. Solo per rendere le cose un po 'più ovvie, più chiare o più facili da capire per i colleghi e anche per te stesso nel mantenere il software.

Sicuramente xp afferma di avere un codice che si spiega da sé, ma fa male un commento di una riga?

Trovo anche molto utili le seguenti regole di questo blog :

  • Comprendi il materiale prima di scrivere
  • Scrivi come se il tuo pubblico fosse in quarta elementare
  • Pensa a come i lettori potrebbero fraintenderti

Chiunque debba tornare nel proprio codice o qualcun altro o anche un codice legacy sa che può essere un mal di testa. Quindi, invece di essere pigro o cercare di essere un supercodificatore nel non commentare nulla o molto poco, perché non rendere il tuo o un povero coglione, che deve mantenere il tuo codice, la vita futura molto più facile seguendo le regole citate.

Anche molte descrizioni di programmazione fatte sono messe in dubbio durante le revisioni e non è sempre chiaro il motivo per cui alcune parti sono state scritte com'erano anche se alcune sezioni di codice sono vitali per il funzionamento di un programma a causa di un grave bug rilevato poiché il codice è stato utilizzato negli anni . Quindi, per non annoiarvi completamente con un tl; dr chiudi con un'ultima citazione di acmqueue :

Una documentazione preventiva, chiara ed estesa è un elemento chiave nella creazione di software in grado di sopravvivere e adattarsi. Documentare secondo standard elevati ridurrà i tempi di sviluppo, migliorerà il lavoro e migliorerà i profitti. È difficile chiedere di più da qualsiasi tecnica.


8
Nel tuo secondo esempio, potresti eliminare del tutto i commenti eseguendo il refactoring: actualDayFuture = padIfSingleDigitDate (actualDayFuture); Questo è banale, ma un esempio più solido trarrebbe beneficio da questo approccio.
Chris Cudmore,

4
Avrei spostato anche il condizionale nel metodo. - Ancora una volta, non per qualcosa di così banale, ma mi permette di ignorare del tutto il pensare alla logica del padding. Non sostituirò il tuo esempio originale, poiché è una risposta migliore alla domanda. È più una nota a margine, esplorare altre alternative.
Chris Cudmore,

1
Annuncio "Sicuramente xp afferma di avere un codice che si spiega da solo, ma fa male un commento di una riga?": I commenti sono buoni, ma c'è anche il pericolo di commentare eccessivamente. Ogni riga di commento è quella che qualcuno potrebbe dimenticare di aggiornare quando cambiano il codice.
Jan Hudec,

1
Un modo migliore per dire questo è "Il miglior tipo di commento è l'assenza della necessità di un commento". I commenti che non sono necessari (ma che sono comunque scritti) non sono buoni commenti.
Kaz,

1
Interessante che il codice di riferimento int directionCode = (x > oldX) ? DIRECTIONCODE_RIGHT : (x > oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;sia in errore. Certamente dovrebbe essere ... (x < oldX) ? DIRECTIONCODE_LEFT : DIRECTIONCODE_NONE;. Buone idee per i commenti - codice errato.
chux,

8

Tendo a ridurre i commenti a entrambi i riferimenti in cui una determinata funzionalità / codice è spiegata in modo più approfondito o spiegare perché viene scelto un certo modo di programmazione.

Considerando che altri programmatori con competenze simili usano o leggono il tuo codice, è importante commentare se usi un modo diverso da quello previsto per raggiungere qualcosa. Quindi puoi spiegare in un commento perché scegli in questo modo.

Ad esempio, se puoi utilizzare due diversi sensori su un dispositivo Android e uno di questi non soddisfa le tue esigenze, puoi spiegare nel commento perché hai scelto l'altro.

Quindi il "perché" dovrebbe dare una logica alle scelte fatte.


5
I riferimenti sono un ottimo esempio. // Questo metodo utilizza l'algoritmo furshclingeheimer per ridistribuire il foobit. Vedi http: // ...
Chris Cudmore,

8

I commenti dovrebbero dirti cosa non fa il codice, non necessariamente delineato da WHY , HOW o WHAT . Se hai un buon nome e hai funzioni ben delineate, è possibile che il codice ti dica esattamente cosa sta succedendo. Per esempio:

List<LightMap> maps = makeLightmaps(receivingModels);
TrianglePartitioner partition = new Octree(castingTriangles);
List<Photon> photons = firePhotons(lights, partition);

if (photons.Count > 0)
{
      PhotonPartitioner photonMap = new KDTree(photons);
      gatherPhotons(maps, photonMap, partition, lights);
}

Questo codice non ha davvero bisogno di commenti. I nomi delle funzioni e dei tipi lo rendono facile da capire.

A volte, tuttavia, può essere difficile o impossibile creare davvero un codice fluente come sopra. Ad esempio, il frammento di codice successivo è per trovare un punto statisticamente casuale su una sfera. La matematica è piuttosto opaca, quindi un commento con un link alla spiegazione è di aiutare a dire come funziona. Questo può essere racchiuso in una funzione per dire COSA fa senza bisogno di un commento se necessario più di una volta, altrimenti il ​​titolo del link aiuta anche in quel dipartimento.

double randomA = localGenerator.NextDouble();
double randomB = localGenerator.NextDouble();

//http://mathworld.wolfram.com/SpherePointPicking.html
double theta = 2 * Math.PI * randomA;
double phi = Math.Acos(2 * randomB - 1);

Vector3 randomDirection = new Vector3(Settings.ambientRayLength * (float)(Math.Cos(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)(Math.Sin(theta) * Math.Sin(phi)),
                                      Settings.ambientRayLength * (float)Math.Cos(phi));

Un altro esempio di quando i commenti indicano cosa non fa il codice è per spiegare una decisione. Nell'esempio seguente, il codice non blocca una variabile non thread locale all'interno di un pezzo di codice thread. C'è una ragione per questo e il commento spiega PERCHÉ . Senza il commento, potrebbe essere considerato un bug o semplicemente non essere notato.

Random random = new Random();
Parallel.For(0, maxPhotons, delegate(int photonIndex, ParallelLoopState state)
{
    ...
    //I don't actually care if this random number is unique between threads, threadsafty is not that big of a deal
    //  in this case and locking the random object could cause a lot of lock contention
    while (random.NextDouble() > reflectProbability)
    {
        ...
    }
    ...
}

Potrebbe, forse, essere migliorato per dire perché l'oggetto casuale non è stato creato all'interno del ciclo parallelo in primo luogo. Se non c'è motivo, potrebbe anche far venire qualcuno e rendersi conto che l'intera idea è stupida ed è un buon posto per il refactoring.


È ragionevole descrivere il codice come non necessitante di commenti quando i commenti sono preceduti da WriteTextanziché da //?

1
Come ho detto nella risposta, i commenti non sono necessari anche se non ci sono dichiarazioni di stampa, tuttavia l'ho modificato per rimuovere le dichiarazioni di stampa al fine di chiarire il punto.
Chewy Gumball,

5

Può essere utile riconoscere diversi tipi di "perché", in particolare:

  • Ragioni per cui quel codice che sembra eccessivamente complesso non funzionerebbe se semplificato (ad esempio un typecast apparentemente superfluo potrebbe essere necessario per garantire che il codice funzioni in alcuni casi angolari).

  • Ragioni per cui alcune particolari operazioni semplici che sembrano pericolose sono effettivamente sicure (ad es. "La nostra routine di recupero dati riporterà un oggetto fittizio oltre l'ultimo come meno di qualsiasi altra cosa, e l'oggetto dopo quello come maggiore; qualsiasi oggetto che dovrebbe ordinare prima che un altro, in una sequenza crescente o decrescente, avrà almeno un altro elemento (possibilmente fittizio) che lo segue ").

In molti casi, un commento del secondo tipo in una parte del codice può "combaciare" con un commento del primo tipo in un'altra (es. "Mentre sembrerebbe che questa sequenza di operazioni possa essere semplificata, la routine di Fitz si basa su il Wongle non viene Woozled fino a dopo che il Bandersnatch è stato Blarped. ")


2

Non dimenticare, se stai scrivendo un programma, non stai solo scrivendo casualmente roba, lo stai facendo perché hai un modello di ciò che vuoi , che sia in un documento formale o solo nella tua testa. La roba nella tua testa è altrettanto reale del software / dei dati di un computer (e altrettanto probabilmente contiene bug).

Qualcuno che legge il tuo codice potrebbe non avere quel modello in testa, quindi i commenti possono servire a dire loro quale era il modello e come il codice si collega ad esso. Penso che sia questo il significato di "perché". Certamente è bene rendere il codice stesso il più autoesplicativo possibile, ma non è sempre abbastanza buono. Esempio:

// transform the x,y point location to the nearest hexagonal cell location
ix1 = (int)floor(0.5 + x + y/2);
iy1 = (int)floor(0.5 + y);

Inoltre, il modello cambia nel tempo e tali modifiche devono essere trasferite al codice. Quindi i commenti non devono solo dire "perché" qualcosa è nel codice, ma altrettanto importante come cambiarlo in risposta alle modifiche anticipate del modello. Esempio:

// to change to square cell locations, remove the "+ y/2" in the above code

Penso che lo scopo dei commenti sia talvolta trascurato.


2
La domanda è chiedere esempi. Potresti aggiungere un esempio per rendere questa risposta più utile?
Bryan Oakley,

2
Il primo pezzo di codice sembra un classico esempio di spiegazione di "cosa" per me. Non che sia un brutto commento, ma non credo che risponda alla domanda del PO.

@Jon: se il commento non fosse presente, il lettore può vedere cosa sta succedendo, ma non ha idea del perché.
Mike Dunlavey,

1
@MikeDunlavey: non sono d'accordo. Non ne ho ancora idea: perché vuoi la posizione della cella esagonale più vicina? Qual è lo scopo di ottenere questa posizione? Interesserebbe qualcosa se cancellassi queste due righe?

2

Non tutti i miei commenti sono del tipo "perché", ma molti lo sono.
Questi sono esempi da un file sorgente (Delphi):

// For easier access to the custom properties:

function GetPrivate: Integer;   // It's an integer field in the external program so let's treat it like that here

// The below properties depend on the ones above or are calculated fields.
// They are kept up-to-date in the OnEventModified event of the TTSynchronizerStorage
// or in the ClientDataSet.OnCalcFields of the TcxDBSchedulerStorage.DataSource.DataSet
property IsModified       : Boolean   read GetIsModified   write SetIsModified;
property IsCatTT          : Boolean   read GetIsCatTT      write SetIsCatTT;
property IsSynced         : Boolean   read GetIsSynced     write SetIsSynced;

lLeftPos := pos(' - [',ASubject); // Were subject and [shiftnaam:act,project,cust] concatenated with a dash?

// Things that were added behing the ] we will append to the subject:

// In the storage the custom value must also be set for:
Self.SetCustomFieldValueByname(cCustFldIsCatTT,Result);

// When we show the custom fields in a grid, the Getters are not executed,
// because the DevEx code does not know about our class helpers.
// So we have two keep both properties synchronized ourselves:

// lNewMasterEvent was set to usUpdated, overwrite because we added:
if ARepair then
  lNewMasterEvent.CustUpdateStatus := usRecreated

// The source occurrence date may have bee changed. Using GetOriginalDate we can retrieve the original date,
// then use that for creating a target occurrence (and update its date):

lNewTTOccurrence.CustSyncEntryID := cSyncEntryID0;    // Backward compatibility with old sync methode

// Single event became recurring or vice versa; replace entire event

// In contradiction to CopySingleEventToTimeTell, CopyMasterEventToTimeTell does not have a ANewStatus parameter
// because master events are always added.

Nota che (mio) perché i commenti di solito precedono il codice che lo farà (quindi finiscono con due punti).

Ho alcuni commenti che spiegano solo ciò che sta accadendo, ad esempio quando un processo ha molti passaggi che hanno un raggruppamento logico (e il codice non viene riformattato per mostrarlo automaticamente), commenterò come:

// Step 1. Initialization

1

Capisco il PERCHÉ come il motivo per cui fai qualcosa in un modo forse strano o forse illogico, a causa delle circostanze date che richiedono di farlo. Il HOW può essere visto nel codice stesso, non importa quanto sia strano, anche se il codice non ha "senso". Il WHAT è probabilmente meglio indicato all'inizio della documentazione di classe / funzione. Questo ti lascia aggiungendo il PERCHÉ , dove spieghi tutto ciò che non è incluso nel COME e COSA, e i modi peculiari che devi prendere a causa di motivi al di fuori del tuo controllo.

Naturalmente non è sempre il caso, al di fuori della terra degli unicorni e degli arcobaleni ...

COME:

foreach($critters as $creature) {
   $creature->dance();
}

CHE COSA:

/* Dancing creatures v1.0
 * 
 * The purpose of this is to make all your critters do the funky dance.
 */

foreach($critters as $creature) {
  $creature->dance();
}

PERCHÉ:

// We had to store the items in an array of objects because of _____ (reason)
foreach($critters as $creature) {
   $creature->dance();
}

5
come risponde alla domanda posta?
moscerino

1
Per citare OP: "Quindi, tornando alla domanda: se i commenti dovessero dirti PERCHÉ, di che cosa stiamo parlando?", E ho risposto a questa domanda: il PERCHÉ di cui si parla è il ragionamento per l'esistenza del dato pezzo di codice.
Juha Untinen,

1
La domanda chiede specificamente degli esempi un paio di volte. Potresti aggiungere un esempio a questa risposta per renderla più utile?
Bryan Oakley,

1
Non penso che nessuno di questi commenti sia effettivamente utile. Se la firma della tua funzione era critters.dance(), il commento ripete semplicemente l'ovvio e "Non siamo riusciti a farlo funzionare in nessun altro modo in cui abbiamo provato" è del tutto inutile. Inoltre, dire "chiameremo il metodo per ogni oggetto" sta ripetendo ciò che il codice dice chiaramente.
Ripristina Monica il

1

Ho imparato SEMPRE a scrivere commenti nei file di intestazione C ++ (poiché non è sempre chiaro COSA fa una funzione, anche se il nome dà un buon suggerimento) soprattutto se si passa un'API ad altri sviluppatori o si utilizza uno strumento per autodoc come Doxygen.

Quindi per me un tipico commento sembra qualcosa del genere

/*** Functionname
/*   What happens here
/*  [in] Params
/*  [out] params
/*** 

L'unica volta che ho usato PERCHÉ i commenti sono cose difficili da capire e talvolta anche per il programmatore, come "NON TOCCARE QUESTO! Perché ..." o "IL PROGRAMMA SI CRESCERA SE LA LINEA È ELIMINATA ..."

Soluzioni alternative, hack e comportamenti strani soddisfano i criteri PERCHÉ ai miei occhi ...

Un esempio molto buono e persino divertente è questa "soluzione alternativa" per un codice incasinato scritto da una persona di nome Richard, qualcun altro lo ha avvolto e ha spiegato perché nei commenti ... https://stackoverflow.com/a/184673/979785

Purtroppo ci sono parecchie volte, in cui sei costretto a avvolgere il toro **** perché non puoi toccare l'originale, o perché "è sempre stato così" o non hai accesso o ... beh, tu non ho il tempo di riparare l'originale allo scopo non si qualifica davvero per l'overhead.


7
Solo che la domanda riguarda i commenti , non la documentazione . In realtà sono cose diverse (il documentationtag è deplorevole ma non si applica ancora alla domanda).
Thomas,

Beh, scusate il fatto che nella mia lingua madre il commento e il commento della documentazione sono usati in modo intercambiabile e quindi con il tag ho pensato che fosse applicabile anche a questa domanda. È davvero un motivo per votare?
AnyOneElse,

2
La domanda chiede un paio di volte per gli esempi di Why commenti, ma l'unico esempio di includere è una cosa commento. Le persone che sfogliano le risposte per esempi potrebbero essere fuorviate dal tuo esempio. Puoi fare un esempio di un commento sul perché ?
Bryan Oakley,

anche se ho detto che ci sono pochissimi WHY nel mio codice e ho nominato due esempi: EDITED ... ecco un link, che sicuramente si qualifica per un WHY
AnyOneElse

@AnyOneElse Non ho votato in negativo. Era lì prima del mio arrivo.
Thomas,

0

Il codice dovrebbe specificare il piano di esecuzione. In questo modo il follower del programma (o il compilatore) può capire cosa fare e come farlo. Ciò che è suddiviso in passaggi che il follower del programma può seguire. I passaggi primitivi sono il come.

L'intento del programmatore è un'altra questione. In un codice semplice, chiaro e chiaro l'intento è ovvio. Qualsiasi lettore umano ragionevolmente esperto arriverà all'intento di un blocco di codice, semplicemente leggendo il codice. La maggior parte del codice dovrebbe leggere in questo modo.

Occasionalmente, il rapporto tra intento e piano è oscuro. Il codice rivela il cosa e il come, ma non il perché. Questo è quando valgono i commenti che rivelano l'intento. L'intenzione del programmatore è il perché.


3
La domanda fa un paio di volte per esempi. Puoi aggiungere un esempio alla tua risposta per renderlo più utile?
Bryan Oakley,

0

Avendo questo problema in questo momento, guadare attraverso stored procedure e viste su un modello di dati complesso e un po 'contorto.

Abbiamo (numerosi) inventato selezioni come "Caso quando x.account non è nullo e x.address in (seleziona indirizzo da fedex) quindi x.account else y.account end" in tutto e la produttività è prevista anche se non c'è tempo a tutto per leggere tutto il codice sorgente. E questo tipo di esempio in qualche modo ha senso, ma è ancora imperscrutabile.

I commenti spiegano perché se in fedex poi xe in caso contrario y - fanno luce sull'intero sistema e quando ne leggiamo abbastanza iniziamo a capirlo. E questo è troppo semplificato e ci sono centinaia o migliaia di affermazioni simili. Il mio cuore brilla calorosamente verso chiunque sia stato il gentile dev del 2007 che ha messo in quelli perché.

Quindi sì, modelli di dati complessi contorti e vedute pelose e procedure memorizzate con più percorsi validamente nominati, per favore per l'amore di Dio ci dica perché.


0

Ho appena scritto questo commento; è un esempio concreto di spiegazione del perché una riga di codice è quella che è, e in particolare del perché l'ho cambiata.

Il metodo esamina i dati memorizzati e valuta se è completo fino ad oggi da un lato e fino alla data di inizio dall'altro.

// In principal, this should be ">=", as we may have data up to the account start
// date but not complete for that day; in practice, 98% of the time if we have
// data for the start date it *is* complete, and requerying it would be a waste
// of time.
while (endDate > accountStartDate)
    ...

Come probabilmente intuirai, l'operatore maggiore di era stato un maggiore o uguale. Il commento spiega perché il vecchio valore ha senso e perché il nuovo valore è migliore. Se qualcuno lo guarda in futuro, vedrà che l'uso di ">" non è una svista, ma un'ottimizzazione. Possono quindi cambiarlo o lasciarlo, in base alle necessità in quel momento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.