Quel est le problème avec les commentaires qui expliquent le code complexe?

236

Beaucoup de gens affirment que "les commentaires devraient expliquer" pourquoi "mais pas" comment "". D'autres disent que "le code devrait être auto-documenté" et que les commentaires devraient être rares. Robert C. Martin affirme que (reformulé selon mes propres mots) souvent "les commentaires sont des excuses pour un code mal écrit".

Ma question est la suivante:

Qu'y a-t-il de mal à expliquer un algorithme complexe ou un morceau de code long et compliqué avec un commentaire descriptif?

De cette façon, au lieu que les autres développeurs (y compris vous-même) aient à lire tout l'algorithme ligne par ligne pour comprendre ce qu'il fait, ils peuvent simplement lire le commentaire descriptif convivial que vous avez écrit en anglais simple.

L'anglais est «conçu» pour être facilement compris par les humains. Java, Ruby ou Perl, cependant, ont été conçus pour concilier lisibilité humaine et lisibilité informatique, compromettant ainsi la lisibilité humaine du texte. Un humain peut comprendre un morceau d'anglais beaucoup plus rapidement qu'il / elle peut comprendre un morceau de code avec le même sens (tant que l'opération n'est pas anodine).

Ainsi, après avoir écrit un morceau de code complexe écrit dans un langage de programmation partiellement lisible par l'homme, pourquoi ne pas ajouter un commentaire descriptif et concis expliquant le fonctionnement du code dans un anglais convivial et compréhensible?

Certains diront que "le code ne devrait pas être difficile à comprendre", "rend les fonctions petites", "utilise des noms descriptifs", "n'écrit pas de code spaghetti".

Mais nous savons tous que cela ne suffit pas. Ce ne sont que des lignes directrices - importantes et utiles - mais elles ne changent pas le fait que certains algorithmes sont complexes. Et sont donc difficiles à comprendre en les lisant ligne par ligne.

Est-ce vraiment si mauvais d'expliquer un algorithme complexe avec quelques lignes de commentaires sur son fonctionnement général? Quel est le problème avec l'explication de code compliqué avec un commentaire?

Aviv Cohn
la source
14
Si c'est compliqué, essayez de le reformer en morceaux plus petits.
Vaughan Hilts
151
En théorie, il n'y a pas de différence entre théorie et pratique. En pratique, il y en a.
Scott Leadley
5
@mattnz: plus directement, au moment où vous écrivez le commentaire, vous êtes plongé dans le problème que ce code résout. La prochaine fois que vous visiterez, vous aurez moins de possibilités avec ce problème .
Steve Jessop
26
"Ce que" la fonction ou la méthode font devrait être évident de son nom. Comment ça se voit, c'est évident à partir de son code. Pourquoi est-ce fait ainsi, quelles hypothèses implicites ont été utilisées, quels papiers il faut lire pour comprendre l'algorithme, etc. - devraient être dans des commentaires.
SK-logic
11
Je pense que beaucoup des réponses ci-dessous interprètent mal intentionnellement votre question. Il n'y a rien de mal à commenter votre code. Si vous estimez avoir besoin d'écrire un commentaire explicatif, alors vous devez le faire.
Tony Ennis

Réponses:

408

En termes simples:

  • Il n'y a rien de mal avec les commentaires en soi. Ce qui ne va pas, c’est d’écrire du code qui a besoin de ce genre de commentaires, ou de supposer qu’il est acceptable d’écrire du code compliqué tant que vous l’expliquez de manière conviviale en anglais clair.
  • Les commentaires ne se mettent pas à jour automatiquement lorsque vous modifiez le code. C'est pourquoi souvent les commentaires ne sont pas synchronisés avec le code.
  • Les commentaires ne rendent pas le code plus facile à tester.
  • S'excuser n'est pas mauvais. Ce que vous avez fait pour cela nécessite des excuses (écrire du code difficile à comprendre) est mauvais.
  • Un programmeur capable d’écrire du code simple pour résoudre un problème complexe vaut mieux que celui qui écrit du code complexe puis écrit un long commentaire expliquant ce que fait son code.

Ligne de fond:

S'expliquer, c'est bien, ne pas avoir besoin de le faire, c'est mieux.

Tulains Córdova
la source
91
Il est souvent impossible de justifier que le code de réécriture des dépenses de l’employeur soit plus explicite, alors qu’un bon commentaire peut faire le travail en beaucoup moins de temps. Un programmeur consciencieux doit utiliser son jugement à chaque fois.
aecolley
34
@aecolley Écrire du code explicite pour commencer, c'est encore mieux.
Tulains Córdova
127
Parfois, un code qui se passe d'explication seul n'est pas assez efficace pour résoudre un problème avec HW & SW d'aujourd'hui. Et la logique métier est notoirement ... sinueuse. Le sous-ensemble de problèmes qui ont des solutions logicielles élégantes est nettement plus petit que l'ensemble des problèmes qu'il est économiquement utile de résoudre.
Scott Leadley
62
@ rwong: à l’inverse, j’ai souvent tendance à écrire plus de commentaires dans la logique métier, car il est important de montrer exactement comment le code s’aligne avec les exigences énoncées: le code pénal ". Si c'est juste un algorithme, eh bien, un programmeur peut déterminer le but à partir de rien s'il est absolument nécessaire. Pour la logique métier, vous avez besoin d'un avocat et du client dans la même pièce en même temps. Peut-être que mon "bon sens" est dans un domaine différent de celui d'un programmeur d'applications moyen ;-)
Steve Jessop
29
@ user61852 Sauf que ce qui est explicite pour vous qui venez d'écrire ce code et de passer la dernière période en plongée n'est peut-être pas explicite pour vous qui doit le maintenir ou le modifier dans cinq ans, sans parler de tous les personnes possibles qui ne sont pas vous qui peuvent avoir à le regarder. "Auto-explicatif" est un saint Graal nébuleux de définitions.
Shadur
110

Il y a un tas de raisons différentes pour que le code soit compliqué ou déroutant. Les raisons les plus courantes sont mieux traitées en refacturant le code afin de le rendre moins déroutant, et non en ajoutant des commentaires de quelque nature que ce soit.

Cependant, il existe des cas où un commentaire bien choisi est le meilleur choix.

  • Si c’est l’ algorithme lui - même qui est compliqué et déroutant, et pas seulement son implémentation - celui qui est écrit dans des revues mathématiques et que l’on appelle plus tard Algorithme de Mbogo -, alors vous mettez un commentaire au tout début de l’implémentation, en lisant quelque chose comme "Ceci est l'algorithme de Mbogo pour la réfringence des widgets, décrit à l'origine ici: [URL du papier]. Cette implémentation contient des améliorations apportées par Alice et Carol [URL d'un autre document]." N'essayez pas d'entrer dans plus de détails que cela; si quelqu'un a besoin de plus de détails, il lui faudra probablement lire tout le papier.

  • Si vous avez pris quelque chose qui peut être écrit sous forme d'une ou deux lignes dans une notation spécialisée et que vous l'avez développé en un gros globes de code impératif, le fait de placer ces une ou deux lignes de notation spécialisée dans un commentaire au-dessus de la fonction est un bon moyen de: dites au lecteur ce qu'il est censé faire. Il s'agit d'une exception à l'argument "mais que se passe-t-il si le commentaire n'est plus synchronisé avec le code", car la notation spécialisée est probablement beaucoup plus facile à trouver que le code. (C'est l'inverse si vous écrivez une spécification en anglais à la place.) Un bon exemple est ici: https://dxr.mozilla.org/mozilla-central/source/layout/style/nsCSSScanner.cpp#1057 ...

    /**
     * Scan a unicode-range token.  These match the regular expression
     *
     *     u\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?
     *
     * However, some such tokens are "invalid".  There are three valid forms:
     *
     *     u+[0-9a-f]{x}              1 <= x <= 6
     *     u+[0-9a-f]{x}\?{y}         1 <= x+y <= 6
     *     u+[0-9a-f]{x}-[0-9a-f]{y}  1 <= x <= 6, 1 <= y <= 6
    
  • Si le code est simple dans son ensemble, mais contient une ou deux choses qui semblent excessivement compliquées, inutiles ou tout simplement fausses, mais qui doivent l'être ainsi pour des raisons, vous mettez un commentaire immédiatement au-dessus du bit suspect, dans lequel vous énoncez les raisons . Voici un exemple simple, où la seule chose à expliquer est la raison pour laquelle une constante a une certaine valeur.

    /* s1*s2 <= SIZE_MAX if s1 < K and s2 < K, where K = sqrt(SIZE_MAX+1) */
    const size_t MUL_NO_OVERFLOW = ((size_t)1) << (sizeof(size_t) * 4);
    if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
        nmemb > 0 && SIZE_MAX / nmemb < size)
      abort();
    
zwol
la source
25
C'est un scandale, 4devrait être CHAR_BIT / 2;-)
Steve Jessop
@SteveJessop: Rien n'empêcherait-il une implémentation où CHAR_BITS16 et sizeof (size_t) étaient 2, mais la valeur maximale de size_t était par exemple 2 ^ 20 [size_t contenant 12 bits de remplissage]?
Supercat
2
@supercat Je ne vois rien qui empêche évidemment cela dans C99, ce qui signifie que cet exemple est techniquement incorrect. Il provient d'une version légèrement modifiée d'OpenBSD reallocarray, et OpenBSD ne croit généralement pas en la possibilité de prendre en charge des possibilités qui ne se produisent pas dans leur ABI.
Zwol
3
@Zack: Si le code est conçu autour d'hypothèses POSIX, utiliser CHAR_BITS pourrait donner l'impression qu'il pourrait fonctionner avec des valeurs autres que 8.
supercat
2
@Zack: pour que les types non signés de largeur exacte soient utiles, leur sémantique doit être définie indépendamment de la taille de int. En l'état uint32_t x,y,z;, la signification de (x-y) > zdépend de la taille de int. En outre, un langage conçu pour écrire du code robuste devrait permettre aux programmeurs de faire la distinction entre un type où les calculs sont censés dépasser la plage du type et devrait envelopper silencieusement, par rapport à un autre lorsque les calculs dépassant la plage du type doivent piéger, et un autre où les calculs ne sont pas censés dépasser la gamme du type, mais ...
Supercat
61

Alors, quel est le problème avec l'explication de code compliqué avec un commentaire?

Ce n'est pas une question de bien ou de mal, mais de la "meilleure pratique", telle que définie dans l'article de Wikipedia :

Une meilleure pratique est une méthode ou technique qui a toujours montré des résultats supérieurs à ceux obtenus avec d'autres moyens et qui est utilisée comme référence.

La meilleure pratique consiste donc à commencer par essayer d’améliorer le code, puis à utiliser l’anglais si cela n’est pas possible.

Ce n'est pas une loi, mais il est beaucoup plus courant de trouver du code commenté nécessitant une refactorisation que du code refactorisé nécessitant des commentaires, ce qui est le cas de la meilleure pratique.

FMJaguar
la source
42
+1 pour "il est beaucoup plus courant de trouver du code commenté qui nécessite une refactorisation qu'un code refactorisé qui nécessite des commentaires"
Brandon
7
D'accord, mais quelle est la fréquence de ce commentaire: //This code seriously needs a refactor
Erik Reppen le
2
Bien entendu, toute prétendue meilleure pratique non étayée par une étude scientifique rigoureuse n'est qu'un avis.
Blrfl
54

Un jour viendra où votre beau code parfaitement conçu, bien structuré et lisible ne fonctionnera pas. Ou cela ne fonctionnera pas assez bien. Ou un cas particulier se présentera où cela ne fonctionne pas et doit être ajusté.

À ce stade, vous devrez faire quelque chose qui change les choses pour que cela fonctionne correctement. Particulièrement dans les cas où il y a des problèmes de performances, mais aussi souvent dans les scénarios où l'une des bibliothèques, API, services Web, gems ou systèmes d'exploitation avec lesquels vous travaillez ne se comporte pas comme prévu, vous pouvez finir par faire des suggestions qui ne le sont pas. nécessairement inélégantes, mais sont contre-intuitives ou non évidentes.

Si vous n'avez pas de commentaires pour expliquer pourquoi vous avez choisi cette approche, il y a de fortes chances que quelqu'un à l'avenir (et même quelqu'un d'autre soit vous) examine le code et voit comment il pourrait être "corrigé" Quelque chose de plus lisible et élégant et annuler par inadvertance votre correctif, car il ne ressemble pas à un correctif.

Si tout le monde écrivait toujours un code parfait, il serait évident que du code qui semble imparfait fonctionne autour d'une intervention délicate du monde réel, mais ce n'est pas ainsi que les choses se passent. La plupart des programmeurs écrivent souvent du code déroutant ou quelque peu enchevêtré, il est donc tout à fait naturel de le ranger. Je jure que mon passé est un idiot à chaque fois que je lis le vieux code que j'ai écrit.

Donc, je ne considère pas les commentaires comme une excuse pour un code incorrect, mais peut-être comme une explication de la raison pour laquelle vous n'avez pas fait la chose évidente. Avoir // The standard approach doesn't work against the 64 bit version of the Frobosticate Librarypermettra aux futurs développeurs, y compris votre futur individu, de faire attention à cette partie du code et de tester cette bibliothèque. Bien sûr, vous pouvez également mettre les commentaires dans vos commits de contrôle de source, mais les utilisateurs ne les examineront qu'après que quelque chose se passe mal. Ils liront les commentaires de code à mesure qu'ils changeront de code.

Les personnes qui nous disent que nous devrions toujours écrire du code théoriquement parfait ne sont pas toujours des personnes ayant une grande expérience de la programmation dans des environnements réels. Parfois, vous devez écrire du code performant à un certain niveau, parfois, vous devez interagir avec des systèmes imparfaits. Cela ne signifie pas que vous ne pouvez pas le faire de manière élégante et bien écrite, mais des solutions non évidentes nécessitent une explication.

Quand j'écris du code pour des projets de loisir que je sais que personne ne lira jamais, je commente encore des parties que je trouve déroutantes - par exemple, toute géométrie 3D implique des maths avec lesquelles je ne suis pas tout à fait à l'aise - parce que je sais quand je reviendrai Dans six mois, j'aurai totalement oublié comment faire ce genre de choses. Ce n'est pas une excuse pour un mauvais code, c'est une reconnaissance d'une limitation personnelle. Tout ce que je ferais en le laissant non commenté, c'est me créer plus de travail à l'avenir. Je ne veux pas que mon futur moi doive réapprendre quelque chose inutilement si je peux l'éviter maintenant. Quelle valeur possible cela aurait-il?

glénatron
la source
5
@Christian c'est ça? La première ligne fait référence à cette affirmation, certes, mais au-delà, elle est un peu plus large si je comprends bien.
Glenatron
9
"Je jure que mon passé est un idiot à chaque fois que je lis le vieux code que j'ai écrit." Après quatre ans de carrière dans le développement, je constate que cela se produit chaque fois que je regarde quelque chose de plus de 6 mois.
Ken
6
Dans de nombreux cas, les informations historiques les plus informatives et les plus utiles se rapportent à des choses considérées mais non décidées. Il existe de nombreux cas où quelqu'un choisit l'approche X pour quelque chose et une autre approche Y semblerait préférable; dans certains de ces cas, Y fonctionnera "presque" mieux que X, mais se révélera avoir des problèmes insurmontables. Si Y était évité à cause de ces problèmes, une telle connaissance peut aider à empêcher les autres de perdre du temps sur des tentatives infructueuses d'implémentation de l'approche Y.
supercat
4
Au quotidien, j'utilise beaucoup les commentaires in-work, ils ne sont pas là pour le long terme, mais il peut être utile de laisser une note TODO ou une courte section pour me rappeler ce que j'allais faire ensuite. rappel dans la matinée.
glenatron
1
@Lilienthal, je ne pense pas que le dernier paragraphe est limitée aux projets personnels , il a dit « ... Je reste un commentaire pièces que je trouve déroutant. »
Wildcard
29

Le besoin de commentaires est inversement proportionnel au niveau d'abstraction du code.

Par exemple, Assembly Language est, dans la plupart des cas, inintelligible sans commentaires. Voici un extrait d' un petit programme qui calcule et imprime les termes de la série de Fibonacci :

main:   
; initializes the two numbers and the counter.  Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
    mov ax,'00'                     ; initialize to all ASCII zeroes
    mov di,counter                  ; including the counter
    mov cx,digits+cntDigits/2       ; two bytes at a time
    cld                             ; initialize from low to high memory
    rep stosw                       ; write the data
    inc ax                          ; make sure ASCII zero is in al
    mov [num1 + digits - 1],al      ; last digit is one
    mov [num2 + digits - 1],al      ; 
    mov [counter + cntDigits - 1],al

    jmp .bottom         ; done with initialization, so begin

.top
    ; add num1 to num2
    mov di,num1+digits-1
    mov si,num2+digits-1
    mov cx,digits       ; 
    call    AddNumbers  ; num2 += num1
    mov bp,num2         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jz  .done           ;

    ; add num2 to num1
    mov di,num2+digits-1
    mov si,num1+digits-1
    mov cx,digits       ;
    call    AddNumbers  ; num1 += num2
.bottom
    mov bp,num1         ;
    call    PrintLine   ;
    dec dword [term]    ; decrement loop counter
    jnz .top            ;
.done
    call    CRLF        ; finish off with CRLF
    mov ax,4c00h        ; terminate
    int 21h             ;

Même avec des commentaires, ça peut être assez compliqué de parler.

Exemple moderne: Les expressions rationnelles sont souvent des constructions d'abstraction très basses (lettres minuscules, chiffres 0, 1, 2, nouvelles lignes, etc.). Ils ont probablement besoin de commentaires sous forme d'échantillons (Bob Martin, IIRC, le reconnaît). Voici une regex qui (je pense) devrait correspondre aux URL HTTP (S) et FTP:

^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\\+&amp;%\$#\=~_\-]+))*$

À mesure que les langues progressent dans la hiérarchie des abstractions, le programmeur peut utiliser des abstractions évocatrices (nom de variable, noms de fonction, noms de classe, noms de module, interfaces, rappels, etc.) pour fournir une documentation intégrée. Négliger d'en tirer parti et utiliser des commentaires sur du papier est paresseux, nuisible et irrespectueux envers le mainteneur.

Je pense Recettes numériques en C traduit la plupart du temps verbatim Recettes numériques en C ++ , que je déduis commencé comme recettes numériques (en FORTAN), avec toutes les variables a, aa, b, c, cc, etc maintenu par chaque version. Les algorithmes étaient peut-être corrects, mais ils ne tiraient pas parti des abstractions fournies par les langages. Et ils me baisent. Échantillon d' un article du Dr. Dobbs - Transformée de Fourier rapide :

void four1(double* data, unsigned long nn)
{
    unsigned long n, mmax, m, j, istep, i;
    double wtemp, wr, wpr, wpi, wi, theta;
    double tempr, tempi;

    // reverse-binary reindexing
    n = nn<<1;
    j=1;
    for (i=1; i<n; i+=2) {
        if (j>i) {
            swap(data[j-1], data[i-1]);
            swap(data[j], data[i]);
        }
        m = nn;
        while (m>=2 && j>m) {
            j -= m;
            m >>= 1;
        }
        j += m;
    };

    // here begins the Danielson-Lanczos section
    mmax=2;
    while (n>mmax) {
        istep = mmax<<1;
        theta = -(2*M_PI/mmax);
        wtemp = sin(0.5*theta);
        wpr = -2.0*wtemp*wtemp;
        wpi = sin(theta);
        wr = 1.0;
        wi = 0.0;
        for (m=1; m < mmax; m += 2) {
            for (i=m; i <= n; i += istep) {
                j=i+mmax;
                tempr = wr*data[j-1] - wi*data[j];
                tempi = wr * data[j] + wi*data[j-1];

                data[j-1] = data[i-1] - tempr;
                data[j] = data[i] - tempi;
                data[i-1] += tempr;
                data[i] += tempi;
            }
            wtemp=wr;
            wr += wr*wpr - wi*wpi;
            wi += wi*wpr + wtemp*wpi;
        }
        mmax=istep;
    }
}

En tant que cas particulier relatif à l'abstraction, chaque langue a des idiomes / extraits de code canoniques pour certaines tâches courantes (suppression d'une liste liée dynamique en C) et, quelle que soit leur apparence, ils ne doivent pas être documentés. Les programmeurs devraient apprendre ces idiomes, car ils font officieusement partie du langage.

Donc, ce qu'il faut enlever: Un code non idiomatique construit à partir de blocs de construction de bas niveau qui ne peuvent pas être évités a besoin de commentaires. Et cela est moins nécessaire que prévu.

Kristian H
la source
1
Personne ne devrait vraiment être en train d' écrire une ligne comme celui - ci en langage assembleur: dec dword [term] ; decrement loop counter. D'autre part, ce qui manque dans votre exemple de langage d'assemblage, c'est un commentaire avant chaque "paragraphe de code" expliquant le rôle du bloc de code suivant. Dans ce cas, le commentaire équivaut généralement à une seule ligne en pseudocode, telle que ;clear the screen, suivie des 7 lignes qu'il faut réellement pour effacer l'écran.
Scott Whitlock
1
Oui, il y a ce que je considérerais comme des commentaires inutiles dans l'échantillon d'assemblage, mais pour être juste, c'est assez représentatif du style d'assemblage 'Bon'. Même avec un prologue de paragraphe d'une ou deux lignes, le code serait vraiment difficile à suivre. J'ai compris mieux l'échantillon ASM que l'exemple FFT. J'ai programmé une FFT en C ++ à l'école supérieure et cela ne ressemblait en rien à cela, mais nous utilisions ensuite la STL, les itérateurs, les foncteurs et de nombreux appels de méthodes. Pas aussi vite que la fonction monolithique, mais beaucoup plus facile à lire. Je vais essayer de l'ajouter pour contraster avec l'exemple NRinC ++.
Kristian H
Vouliez-vous dire ^(((ht|f)tps?)\:\/\/)?(www\.)*[a-zA-Z0-9\-\.]+\.(com|edu|gov|mil|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\,\;\?\'\\\+&%\$#\=~_\-]+))*$? Soyez conscient des adresses numériques.
izabera
Plus ou moins ce que je veux dire: certaines choses construites à partir d'abstractions de très bas niveau ne sont pas faciles à lire ou à vérifier. Les commentaires (et, pour ne pas trop vous écarter du sujet, les TESTS) peuvent être utiles et non préjudiciables. En même temps, le fait de ne pas utiliser les abstractions de niveau supérieur disponibles (: alpha:: num: le cas échéant) rend la compréhension plus difficile, même avec de bons commentaires, que d’utiliser des abstractions de niveau supérieur.
Kristian H
3
+1: "The need for comments is inversely proportional to the abstraction level of the code." Tout y est bien résumé.
Gerrat le
21

Je ne crois pas qu'il y ait quelque chose qui cloche dans les commentaires dans le code. L'idée que les commentaires sont en quelque sorte mauvais à mon avis est due à certains programmeurs qui vont trop loin. Il y a beaucoup de mouvement dans cette industrie, en particulier vers les points de vue extrêmes. Quelque part en cours de route, le code commenté est devenu équivalent à un mauvais code et je ne sais pas pourquoi.

Les commentaires ont des problèmes - vous devez les garder à jour lorsque vous mettez à jour le code auquel ils font référence, ce qui arrive beaucoup trop rarement. Un wiki ou quelque chose est une ressource plus appropriée pour une documentation complète sur votre code. Votre code doit être lisible sans nécessiter de commentaires. Les notes de contrôle de version ou de révision doivent correspondre aux modifications que vous avez apportées au code.

Rien de ce qui précède n'invalide toutefois l'utilisation de commentaires. Nous ne vivons pas dans un monde idéal. Par conséquent, si l'un de ces problèmes échouait pour une raison quelconque, je préférerais avoir quelques commentaires à faire.

Roy
la source
18

Je pense que vous en lisez un peu trop dans ce qu'il dit. Votre plainte comporte deux parties distinctes:

Qu'est-ce qui ne va pas avec l'explication (1) d'un algorithme complexe ou (2) d'un morceau de code long et compliqué avec un commentaire descriptif?

(1) est inévitable. Je ne pense pas que Martin serait en désaccord avec vous. Si vous écrivez quelque chose comme la racine carrée rapide rapide inverse , vous aurez besoin de quelques commentaires, même s'il ne s'agit que d'un "piratage malveillant au niveau des bits en virgule flottante". À l'exception de quelque chose de simple, comme une recherche DFS ou binaire, il est peu probable que la personne qui lit votre code ait une expérience de cet algorithme, et je pense donc qu'il devrait y avoir au moins une mention à ce sujet dans les commentaires.

La plupart du code n'est pas (1), cependant. Rarement écrirez-vous un logiciel qui n’est autre chose que des implémentations mutex roulées à la main, des opérations d’algèbre linéaire obscures avec un support médiocre des bibliothèques et de nouveaux algorithmes connus uniquement du groupe de recherche de votre entreprise. La plupart du code comprend des appels de bibliothèque / framework / API, des entrées-sorties, des tests passe-partout et des tests unitaires.

C'est le genre de code dont parle Martin. Et il répond à votre question en citant Kernighan et Plaugher en haut du chapitre:

Ne commentez pas le mauvais code, réécrivez-le.

Si vous avez de longues sections compliquées dans votre code, vous n'avez pas réussi à garder votre code propre . La meilleure solution à ce problème n'est pas d'écrire un commentaire long d'un paragraphe en haut du fichier pour aider les futurs développeurs à s'y débrouiller; la meilleure solution est de le réécrire.

Et c'est exactement ce que dit Martin:

L'utilisation appropriée des commentaires sert à compenser notre incapacité à nous exprimer en code ... Les commentaires sont toujours des échecs. Nous devons les avoir car nous ne pouvons pas toujours comprendre comment nous exprimer sans eux, mais leur utilisation n’est pas un motif de célébration.

Ceci est votre (2). Martin convient que le code long et compliqué a besoin de commentaires - mais il blâme ce programmeur sur les épaules du programmeur qui l'a écrit, pas une idée nébuleuse selon laquelle "nous savons tous que cela ne suffit pas". Il soutient que:

Un code clair et expressif avec peu de commentaires est de loin supérieur à un code encombré et complexe avec beaucoup de commentaires. Plutôt que de passer votre temps à écrire les commentaires qui expliquent le désordre que vous avez causé, passez-le à nettoyer ce désordre.

Patrick Collins
la source
3
Si un développeur avec lequel je travaillais écrivait simplement "piratage de niveau binaire en virgule flottante maléfique" pour expliquer l'algorithme de racine carrée rapide, il me parlerait. Tant qu'ils incluraient une référence à un endroit plus utile, je serais heureux cependant.
Michael Anderson
8
Je ne suis pas d'accord d'un point de vue - un commentaire expliquant comment quelque chose de mal fonctionne est beaucoup plus rapide. Compte tenu du code qui ne sera probablement plus touché (la plupart du code, je suppose), un commentaire est une meilleure solution métier qu'un grand refactoring, qui introduit souvent des bogues (car un correctif qui tue un bogue invoqué est toujours un bogue). Un monde parfait de code parfaitement compréhensible ne nous est pas accessible.
gbjbaanb
2
@trysis haha, oui, mais dans un monde où les programmeurs sont responsables et non des hommes d’affaires, ils n’enverront jamais car ils plaquent à jamais une base de code constamment refactorisée dans une vaine quête de perfection.
gbjbaanb
4
@ PatrickCollins presque tout ce que je lis sur le Web parle de le faire correctement du premier coup. Presque personne ne veut écrire des articles sur la réparation des dégâts! Physiciens dire « donné une sphère parfaite ... » Comp.Scientists dire « donné un développement entièrement nouveau ... »
gbjbaanb
2
La meilleure solution consiste à le réécrire dans un délai infini. mais compte tenu de la base de code de quelqu'un d'autre, des délais habituels d'une entreprise et de la réalité; Parfois, la meilleure chose à faire est de commenter, d’ajouter un TODO: Refactor et d’obtenir ce refactor dans la prochaine version; et ce correctif qui devait être fait hier fait maintenant. Le problème à propos de tout ce discours idéaliste à propos de la simple refactorisation est qu’il ne tient pas compte de la façon dont les choses fonctionnent réellement sur le lieu de travail; il arrive parfois que les priorités soient plus élevées et que les délais soient suffisamment courts pour empêcher la résolution du code de mauvaise qualité hérité. C'est comme ça.
Hsanders
8

Qu'y a-t-il de mal à expliquer un algorithme complexe ou un morceau de code long et compliqué avec un commentaire descriptif?

Rien en tant que tel. Documenter votre travail est une bonne pratique.

Cela dit, vous avez une fausse dichotomie: écrire du code propre ou écrire du code documenté - les deux ne sont pas opposés.

Vous devez vous concentrer sur la simplification et la synthèse du code complexe en un code plus simple, au lieu de penser "un code complexe est acceptable tant qu'il est commenté".

Idéalement, votre code devrait être simple et documenté.

De cette façon, au lieu que les autres développeurs (y compris vous-même) aient à lire tout l'algorithme ligne par ligne pour comprendre ce qu'il fait, ils peuvent simplement lire le commentaire descriptif convivial que vous avez écrit en anglais simple.

Vrai. C’est pourquoi tous vos algorithmes d’API publics doivent être expliqués dans la documentation.

Ainsi, après avoir écrit un morceau de code complexe écrit dans un langage de programmation partiellement lisible par l'homme, pourquoi ne pas ajouter un commentaire descriptif et concis expliquant le fonctionnement du code dans un anglais convivial et compréhensible?

Idéalement, après avoir écrit un morceau de code complexe, vous devriez (non pas une liste exhaustive):

  • considérez-le comme une ébauche (c.-à-d. prévoyez le réécrire
  • formaliser les points d'entrée / interfaces / rôles / etc. de l'algorithme (analyser et optimiser l'interface, formaliser les abstractions, documenter les conditions préalables, post-conditions et effets secondaires et documenter les cas d'erreur).
  • écrire des tests
  • nettoyage et refactor

Aucune de ces étapes n’est triviale (c’est-à-dire que chacune peut durer quelques heures) et les récompenses qui en découlent ne sont pas immédiates. En tant que telles, ces étapes sont (presque) toujours compromises (par les développeurs qui coupent les coins, les directeurs qui coupent, les délais, les contraintes du marché / autres conditions du monde réel, le manque d'expérience, etc.).

[...] certains algorithmes sont complexes. Et sont donc difficiles à comprendre en les lisant ligne par ligne.

Vous ne devriez jamais avoir à lire l’implémentation pour savoir ce que fait une API. Lorsque vous faites cela, vous implémentez du code client basé sur l'implémentation (au lieu de l'interface) et cela signifie que votre couplage de module est déjà foutu, vous introduisez potentiellement des dépendances non documentées avec chaque nouvelle ligne de code que vous écrivez, et ajoutant déjà une dette technique.

Est-ce vraiment si mauvais d'expliquer un algorithme complexe avec quelques lignes de commentaires sur son fonctionnement général?

Non, c'est bien. Ajouter quelques lignes de commentaires ne suffit toutefois pas.

Quel est le problème avec l'explication de code compliqué avec un commentaire?

Le fait que vous ne devriez pas avoir de code compliqué, si cela peut être évité.

Pour éviter le code compliqué, formalisez vos interfaces, consacrez environ 8 fois plus de ressources à la conception d’API qu’à vos dépenses d’implémentation (Stepanov a suggéré de dépenser au moins 10 fois plus sur l’interface, par rapport à l’implémentation), puis développez un projet en sachant vous créez un projet, pas seulement l'écriture d'un algorithme.

Un projet implique une documentation API, une documentation fonctionnelle, des mesures de code / qualité, une gestion de projet, etc. Aucun de ces processus ne constitue une étape unique et rapide à effectuer (ils prennent tous du temps, nécessitent de la prévoyance et de la planification, et ils exigent tous que vous y reveniez périodiquement et que vous les révisiez / les complétiez avec des détails).

utnapistim
la source
3
"Vous ne devriez jamais avoir à lire l’implémentation pour savoir ce que fait une API." Parfois, cela vous est infligé par un amont que vous vous êtes engagé à utiliser. J'avais un projet particulièrement insatisfaisant encombré de commentaires de la forme "le code honteux de Heath Robinson suivant existe parce que simpleAPI () ne fonctionne pas correctement sur ce matériel en dépit de ce que prétend le fournisseur".
pjc50
6

au lieu que d'autres développeurs (y compris vous-même) soient obligés de lire ligne par ligne l'intégralité de l'algorithme pour comprendre ce qu'il fait, ils peuvent simplement lire le commentaire descriptif sympathique que vous avez écrit en anglais simple.

Je considérerais cela comme un léger abus de "commentaires". Si le programmeur veut lire quelque chose au lieu de tout l'algorithme, c'est à cela que sert la documentation de la fonction. OK, la documentation de la fonction peut en fait apparaître dans les commentaires du source (peut-être pour l'extraction à l'aide d'outils de documentation), mais même si, syntaxiquement, il s'agit d'un commentaire pour le compilateur, vous devez les considérer comme des éléments distincts ayant des objectifs distincts. Je ne pense pas que «les commentaires devraient être rares» signifie nécessairement «la documentation devrait être rare» ou même «les avis de droit d'auteur devraient être rares»!

Les commentaires dans la fonction sont à lire , ainsi que le code. Donc, si votre code contient quelques lignes difficiles à comprendre et que vous ne pouvez pas les rendre faciles à comprendre, un commentaire est utile pour le lecteur à utiliser comme espace réservé pour ces lignes. Cela pourrait être très utile pendant que le lecteur essaie juste de comprendre l'essentiel, mais il y a quelques problèmes:

  • Les commentaires ne sont pas nécessairement vrais, alors que le code fait ce qu'il fait. Donc, le lecteur prend votre mot pour cela, et ce n'est pas idéal.
  • Le lecteur ne comprend pas encore le code lui-même et, jusqu'à ce qu'il y revienne plus tard, il n'est toujours pas qualifié pour le modifier ou le réutiliser. Dans quel cas que font-ils lire?

Il existe des exceptions, mais la plupart des lecteurs devront comprendre le code lui-même. Les commentaires doivent être écrits pour faciliter cela, pas pour les remplacer. C'est pourquoi on vous conseille généralement de dire "pourquoi vous le faites". Un lecteur qui connaît la motivation pour les prochaines lignes de code a de meilleures chances de voir ce qu’il fait et comment.

Steve Jessop
la source
5
Un endroit utile pour les commentaires: dans le code scientifique, vous pouvez souvent avoir des calculs assez complexes, impliquant beaucoup de variables. Pour le bon sens du programmeur, il est logique de garder les noms de variable très courts, afin que vous puissiez regarder les maths plutôt que les noms. Mais cela rend vraiment difficile à comprendre pour le lecteur. Donc, une brève description de ce qui se passe (ou mieux, une référence à l'équation dans un article de journal ou similaire) peut être vraiment utile.
naught101
1
@ naught101: oui, d'autant plus que le document dont vous parlez utilise aussi probablement des noms de variables d'une seule lettre. Il est généralement plus facile de voir que le code suit effectivement le papier si vous utilisez les mêmes noms, mais cela est en contradiction avec l'objectif du code d'être explicite (c'est expliqué par le papier à la place). Dans ce cas, un commentaire dans lequel chaque nom est défini, en précisant sa signification réelle, remplace les noms significatifs.
Steve Jessop
1
Lorsque je recherche quelque chose de spécifique dans le code (où cette affaire est-elle traitée?), Je ne veux pas lire ni comprendre les paragraphes de code simplement pour découvrir que ce n'est pas l'endroit. J'ai besoin de commentaires qui résument en une seule ligne ce que fait le paragraphe suivant. De cette façon, je localiserai rapidement les parties de code liées à mon problème et ignorerai les détails sans intérêt.
Florian F
1
@FlorianF: la réponse traditionnelle est que les noms de variable et de fonction doivent indiquer en gros le contenu du code, ce qui vous permet de survoler des éléments qui ne correspondent certainement pas à ce que vous recherchez. Je suis d'accord avec vous pour dire que cela ne réussit pas toujours, mais je ne suis pas tellement d'accord que je pense que tout le code doit être commenté pour faciliter la recherche ou la lecture rapide. Mais vous avez raison, c'est un cas où quelqu'un lit votre code (en quelque sorte) et n'a légitimement pas besoin de le comprendre.
Steve Jessop
2
@Snowman Les gens pourraient le faire avec des noms de variables. J'ai vu le code où la variable listOfApples contenait une liste de bananes. Quelqu'un a copié le code traitant la liste des pommes et l'a adapté pour Bananas sans changer les noms des variables.
Florian F
5

Nous devons souvent faire des choses compliquées. Il est certainement juste de les documenter pour une compréhension future. Parfois, le bon endroit pour cette documentation est dans le code, où la documentation peut être tenue à jour avec le code. Mais cela vaut vraiment la peine d’envisager une documentation séparée. Cela peut également être plus facile à présenter à d’autres personnes, notamment des diagrammes, des images en couleur, etc. Alors le commentaire est juste:

// This code implements the algorithm described in requirements document 239.

ou même juste

void doPRD239Algorithm() { ...

Les gens sont certainement satisfaits des fonctions nommées MatchStringKnuthMorrisPrattou encryptAESou partitionBSP. Des noms plus obscurs méritent d’être expliqués dans un commentaire. Vous pouvez également ajouter des données bibliographiques et un lien vers un document à partir duquel vous avez implémenté un algorithme.

Si un algorithme est complexe, nouveau et peu évident, il vaut certainement un document, même s'il ne concerne que la circulation interne à l'entreprise. Vérifiez le document dans le contrôle de source si vous craignez de le perdre.

Il existe une autre catégorie de code qui n’est pas tant algorithmique que bureaucratique. Vous devez configurer les paramètres d'un autre système ou interagir avec les bogues de quelqu'un d'autre:

/* Configure the beam controller and turn on the laser.
The sequence is timing-critical and this code must run with interrupts disabled.
Note that the constant 0xef45ab87 differs from the vendor documentation; the vendor
is wrong in this case.
Some of these operations write the same value multiple times. Do not attempt
to optimise this code by removing seemingly redundant operations.
*/
pjc50
la source
2
Je m'opposerais à l'attribution de noms aux fonctions / méthodes d'après leur algorithme interne. La plupart du temps, la méthode utilisée doit être une préoccupation interne. Décrivez le sommet de votre fonction avec la méthode utilisée, mais ne m'appelez pas cela doPRD239Algorithmme dit rien sur la fonction sans avoir à chercher l'algorithme, la raison MatchStringKnuthMorrisPrattet le encryptAEStravail est qu'ils commencent par une description de ce qu'ils font, puis suivent avec une description de la méthodologie.
Scragar
5

J'oublie l'endroit où je l'ai lu, mais il existe une ligne de démarcation nette entre ce qui devrait apparaître dans votre code et ce qui devrait apparaître comme un commentaire.

Je crois que vous devriez commenter votre intention, pas votre algorithme . C'est-à-dire commenter ce que vous vouliez faire, pas sur ce que vous faites .

Par exemple:

// The getter.
public <V> V get(final K key, Class<V> type) {
  // Has it run yet?
  Future<Object> f = multitons.get(key);
  if (f == null) {
    // No! Make the task that runs it.
    FutureTask<Object> ft = new FutureTask<Object>(
            new Callable() {

              public Object call() throws Exception {
                // Only do the create when called to do so.
                return key.create();
              }

            });
    // Only put if not there.
    f = multitons.putIfAbsent(key, ft);
    if (f == null) {
      // We replaced null so we successfully put. We were first!
      f = ft;
      // Initiate the task.
      ft.run();
    }
  }
  try {
    /**
     * If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
     * then you are trying to get from your Multiton in your creator.
     *
     * Cannot check for that without unnecessarily complex code.
     *
     * Perhaps could use get with timeout.
     */
    // Cast here to force the right type.
    return (V) f.get();
  } catch (Exception ex) {
    // Hide exceptions without discarding them.
    throw Throwables.asRuntimeException(ex);
  }
}

Ici, il n’ya aucune tentative d’énoncer ce que chaque étape exécute, tout ce qu’elle énonce est ce qu’elle est supposée faire.

PS: J'ai trouvé la source à laquelle je faisais allusion - Coder l'horreur: le code vous dit comment, les commentaires vous disent pourquoi

Vieux curcuma
la source
8
Le premier commentaire: est-ce qu'il a déjà fonctionné? A quoi courir encore? Même chose pour les autres commentaires. Pour quelqu'un qui ne sait pas ce que le code fait, c'est inutile.
gnasher729
1
@ gnasher729 - Hors de leur contexte, presque tous les commentaires seront inutiles - ce code est une démonstration de l'ajout de commentaires indiquant une intention plutôt que d'une tentative de description . Je suis désolé que cela ne fait rien pour vous.
OldCurmudgeon
2
Un mainteneur de ce code n'aura pas de contexte. Il n’est pas particulièrement difficile de comprendre ce que fait le code, mais les commentaires n’aident pas. Si vous écrivez des commentaires, prenez votre temps et concentrez-vous lorsque vous les écrivez.
gnasher729
BTW - Le commentaire " Est-ce qu'il a déjà été lancé?" Fait référence à Futureet indique qu'un get()suivi par une vérification nulldétecte si le Futurea déjà été exécuté - documentant correctement l' intention plutôt que le processus .
OldCurmudgeon
1
@ Old Curmudgeon: Votre réponse est assez proche de ce que je pensais, je vais juste ajouter ce commentaire comme exemple de votre argument. Bien qu'un commentaire ne soit pas nécessaire pour expliquer le code propre, un commentaire est utile pour expliquer pourquoi le codage a été effectué d'une manière sur l'autre. Dans mon expérience limitée, les commentaires sont souvent utiles pour expliquer les particularités de l'ensemble de données sur lequel le code travaille, ou les règles de gestion que le code est censé appliquer. Le code de commentaire ajouté pour corriger un bogue est un bon exemple, si ce bogue s’est produit parce qu’une hypothèse concernant les données était erronée.
Randall Stewart
4

Mais nous savons tous que cela ne suffit pas.

Vraiment? Depuis quand?

Un code bien conçu avec de bons noms est largement suffisant dans la grande majorité des cas. Les arguments contre l'utilisation de commentaires sont bien connus et documentés (comme vous le mentionnez).

Mais ce sont des lignes directrices (comme toute autre chose). Dans les rares cas (d'après mon expérience, environ une fois tous les deux ans) où la situation s'aggraverait si elle était reformulée en fonctions lisibles plus petites (en raison de performances ou de besoins de cohésion), puis allez de l'avant - mettez un long commentaire expliquant ce qu'est réellement l'objet faire (et pourquoi vous enfreignez les meilleures pratiques).

Telastyn
la source
7
Je sais que ce n'est pas suffisant.
Florian F
2
Depuis quand? Apparemment, vous connaissez déjà la réponse à cette question. "Un code bien conçu avec de bons noms est largement suffisant dans la grande majorité des cas." Donc, ce n'est probablement pas suffisant dans une minorité de cas, ce qui est exactement ce que demande le demandeur.
Ellesedil
3
J'essaie toujours de déchiffrer le code d'autres personnes à qui, je souhaite, j'avais ajouté quelques commentaires plus d'une fois tous les deux ans.
Ogre Psalm33
@ OgrePsalm33 - Ont-ils de petites méthodes et utilisent-ils de bons noms? Mauvais code est mauvais, indépendamment des commentaires.
Telastyn
2
@Telastyn Malheureusement, lorsque vous travaillez sur une base de code volumineuse, les "petites" méthodes et les "bons" noms sont subjectifs pour chaque développeur (c'est donc un bon commentaire, d'ailleurs). Un développeur qui écrit du code d’algorithme de traitement graphique Flarbigan pendant 7 ans peut écrire quelque chose de parfaitement clair pour lui et les développeurs similaires, mais serait mystérieux pour le nouveau type qui a passé les 4 dernières années à développer le code d’infrastructure de grille Perbian. Deux semaines plus tard, l’expert Flarbigan s’arrête.
Ogre Psalm33
2

Le but principal du code est de commander à un ordinateur de faire quelque chose. Un bon commentaire ne remplace donc jamais un bon code car les commentaires ne peuvent pas être exécutés.

Cela étant dit, les commentaires dans le source constituent une forme de documentation pour les autres programmeurs (y compris vous-même). Si les commentaires portent sur des problèmes plus abstraits que ce que le code fait à chaque étape, vous vous en sortez mieux que la moyenne. Ce niveau d'abstraction varie selon l'outil que vous utilisez. Les commentaires accompagnant les routines de langage d'assemblage ont généralement un niveau "d'abstraction" inférieur à celui, par exemple, de cet APL A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕. Je pense que cela mériterait probablement un commentaire sur le problème qu'il est censé résoudre, hmmm?

Scott Leadley
la source
2

Si le code est trivial, il n'a pas besoin de commentaire explicatif. Si le code est non trivial, le commentaire explicatif le sera probablement également.

Maintenant, le problème avec le langage naturel non trivial est que beaucoup d’entre nous ne sommes pas très doués pour le lire ou l’écrire. Je suis sûr que vos compétences en communication écrite sont excellentes, mais néanmoins, une personne ayant une compréhension moindre de la langue écrite pourrait mal comprendre vos mots.

Si vous essayez très fort d’écrire un langage naturel qui ne peut pas être mal interprété, vous obtenez quelque chose comme un document juridique (et comme nous le savons tous, ceux-ci sont plus verbeux et difficiles à comprendre que le code).

Le code devrait être la description la plus concise de votre logique, et il ne devrait pas y avoir beaucoup de débats sur la signification de votre code car votre compilateur et votre plate-forme ont le dernier mot.

Personnellement, je ne dirais pas que vous ne devriez jamais écrire de commentaire. Seulement, vous devriez considérer pourquoi votre code a besoin d'un commentaire et comment vous pouvez le résoudre. Cela semble être un thème commun dans les réponses ici.

Martin
la source
Exactement ce à quoi je pensais lorsque je ne suis pas d’accord avec l’affirmation "Un humain peut comprendre un élément de l'anglais beaucoup plus rapidement qu'il / elle peut comprendre un élément de code ayant le même sens (tant que l'opération n'est pas anodine)" toujours moins ambigu et plus concis.
stephenbayer le
0

Un point qui n’a pas encore été mentionné est que, parfois, il peut être utile de commenter précisément ce qu’est un code, dans les cas où une langue utilise une syntaxe particulière à des fins multiples. Par exemple, en supposant que toutes les variables sont de type float, considérons:

f1 = (float)(f2+f3); // Force result to be rounded to single precision
f4 = f1-f2;

La transposition explicite de a a floatpour effet floatde forcer le résultat à être arrondi à une seule précision; le commentaire pourrait donc être vu comme disant simplement ce que le code fait. D'autre part, comparez ce code avec:

thing.someFloatProperty = (float)(f2*0.1); // Divide by ten

Ici, l'objectif de la distribution est d'empêcher le compilateur de grignoter de la manière la plus efficace pour calculer avec précision (f2 / 10) [plus précis que multiplier par 0,1f, et sur la plupart des machines, il est plus rapide que de diviser par 10.0f].

Sans le commentaire, quelqu'un qui examinait l'ancien code pourrait penser que la distribution a été ajoutée, persuadée à tort qu'il serait nécessaire d'empêcher le compilateur de crier et que cela n'était pas nécessaire. En fait, la distribution a exactement le même objectif: forcer le résultat du calcul à être arrondi à simple précision, même sur des machines où l'arrondi serait plus coûteux que de conserver le résultat avec une précision supérieure. Etant donné qu'un acteur floatpeut avoir un certain nombre de significations et d'objectifs différents, un commentaire spécifiant quelle signification est prévue dans un scénario particulier peut aider à préciser que la signification réelle est alignée sur l'intention.

supercat
la source
Je ne suis pas sûr que J. Random Programmer, en regardant le deuxième exemple, réalise que la constante est écrite 0.1 pour une bonne raison, plutôt que parce que le programmeur d'origine a oublié de taper un 'f'.
David K
En particulier lors du débogage, vous ne supposez jamais que quelque chose a été fait pour une bonne raison.
gnasher729
@ DavidK: Mon deuxième exemple de code avait pour but de le contraster avec le premier morceau de code. Dans le deuxième morceau de code, l'intention du programmeur est probablement d'avoir someFloatPropertyla représentation la plus précise f2/10possible. Le but principal de la deuxième distribution est donc simplement de compiler le code . Dans le premier exemple, cependant, le transtypage n'est clairement pas nécessaire pour son objectif normal (changement d'un type de compilation à un autre) car les opérandes le sont déjà float. Le commentaire sert à préciser que la distribution est nécessaire à des fins secondaires (arrondi).
Supercat
Je suis d'accord avec l'idée qu'il n'est pas nécessaire de faire de commentaire sur le (float)casting dans le deuxième exemple. La question concerne la constante littérale 0.1. Vous avez expliqué (dans le paragraphe suivant) pourquoi nous 0.1écrivions: "c'est plus précis que multiplier par 0.1f". Je suggère que ce sont les mots qui devraient être dans le commentaire.
David K
@DavidK: J'aurais certainement inclus le commentaire si je savais que 0.1f serait trop imprécis, et utiliserais 0.1f si je savais que la perte de précision serait acceptable et que 0.1f serait en réalité sensiblement plus rapide que 0.1 . Si je ne connais aucune de ces affirmations, je préférerais que mon habitude de codage soit utilisée doublepour les constantes ou les calculs intermédiaires dont la valeur peut ne pas être représentable, floatbien que peut pousser soit à utiliser des floatconstantes non pas pour la vitesse, mais pour minimiser la gêne].
Supercat
-1

Les commentaires qui expliquent ce que fait le code sont une forme de duplication. Si vous modifiez le code puis oubliez de mettre à jour les commentaires, cela peut entraîner une confusion. Je ne dis pas que ne les utilisez pas, mais utilisez-les judicieusement. Je souscris à la maxime d'Oncle Bob: "Ne commentez que ce que le code ne peut pas dire".

murungu
la source