/* Sans commentaires */

On voit trop souvent, sur les forums, des bouts de code dans le style :

i++; /* Incrémente la variable i. */

Si ce commentaire vous paraît tout à fait naturel et correct, et que vous n'êtes pas un grand débutant en programmation, cet article est fait pour vous.

En code comme en français, on évite les répétitions

Vous vous demandez probablement pourquoi je pousse un coup de gueule contre un commentaire qui paraît tout à fait naturel et correct. Pour le comprendre, posons-nous la question : pourquoi commente-t-on nos code ?

On vous a sûrement appris qu'un code est écrit une fois, alors qu'il est lu de nombreuses fois, et qu'ainsi les commentaires sont importants pour aider les gens qui vont être amenés à lire vos codes à comprendre ce que vous avez voulu dire. Là est la clé : aider à comprendre.

Or, si l'on reprend notre exemple :

i++; /* Incrémente la variable i. */
		

On voit que le commentaire n'aide pas. En effet, quiconque programme en langage C saura très bien que cette instruction va incrémenter i, et même de nombreux programmeurs ne pratiquant pas le C l'auraient deviné.

Ainsi, tous les commentaires qui se contentent de traduire le code en français sont inutiles, et devraient être supprimés. Il y a bien sûr quelques exceptions, par exemple dans les tutoriels, si vous présentez un code inconnu des lecteurs. Mais dans le cas général, où vous savez à peu près programmer et que vous codez un projet, vous devriez vous abstenir d'en écrire.

Cependant, la plupart du temps, les commentaires redondants sont rendus nécessaires par la façon dont le code est écrit. En effet, si vous utilisez des noms comme « n » ou « ajoutCmt » pour vos varibles et fonctions, vous allez être obligés d'expliquer avec un commentaire ce qu'un meilleur nom, comme « nombreVisiteurs » ou « ajouterCommentaire », aurait pu montrer directement : à quoi sert la fonction ou la variable.

La première étape pour écire de bons commentaires est donc d'écrire du bon code, avec des noms corrects et une bonne structuration. En effet, il existe un piège qui consiste en écrire du code affreux, mais bardé de commentaires qui servent d'excuse : « oui mais les commentaires permettent de comprendre ». Un code autosuffisant, qui se comprend directement, sera toujours plus agréable à lire et à modifier qu'un code qui nécéssite de lire beaucoup de commentaires pour le comprendre.

Le tout est de trouver un équilibre : écrire le code le plus clair possible, puis commenter les passages les plus difficiles. Grâce à celà, on évite beaucoup de commentaires inutiles et on se concentre sur l'essentiel : éclairer le sens du code.

Pour revenir à notre exemple, on voit que notre ligne incrémente la variable i, qui, vu son nom, est certainement un compteur ou un index1. Mais pourquoi faisons-nous cela ? Qu'est-ce que cette incrémentation va changer dans le programme ? Ce sont le genre de questions dont un programmeur extérieur aimerait bien avoir la réponse. Et ce sont aux commentaires du programme de les lui fournir. Ainsi, si l'on écrit :

i++; /* Passe à la case suivante. */
		

On peut en déduire que, dans ce contexte, i est très probablement un index qui permet de parcourir un tableau case par case, dans l'odre (vu que i croit de un en un). Cette ligne se situe donc forcément à la fin de l'analyse de la case du tableau. Enfin, vu ce qu'on a pu déduire du contexte, il y a 99% de chances que cette ligne se situe dans une boucle.

Il est assez impressionant de voir comment, en changeant l'ancien commentaire par un autre de même longueur (au caractère près :-), on a pu permettre à un hypothétique programmeur extérieur de deviner une foule de choses, non seulement sur la ligne elle-même, mais également sur le code autour - dont nous ne disposons pas ici. Simplement en lisant cette ligne, nous avons pu comprendre le sens du bloc d'instructions (vous savez, ce qui est délimité par des { et } en C) qui l'englobe.

Mission accomplie : grâce à notre nouveau commentaire, le sens du code est maintenant beaucoup plus clair.

Quelques techniques

Il existe une technique assez sympathique pour commenter une fonction correctement. Tout d'abord, il faut s'imaginer que vous vouliez faire coder votre fonction par un[e] ami[e], et pas par vous même. Le hic, c'est que vous ne savez pas dans quel langage celui-ci [celle-ci] va programmer. Vous allez donc lui décrire le code que vous voulez, en lui expliquant à chaque fois pourquoi on fait telle ou telle chose. On obtiendra un résultat du style :

On écrit une fonction qui reçoit un tableau d'entiers avec sa taille, et qui un entier : le plus grand élément du tableau.
		On parcourt le tableau du début à la fin, en gardant dans une variable la plus grande valeur dans le tableau trouvée jusqu'à maintenant.
		À chaque étape, on met à jour ce maximum si nécéssaire.
		Enfin, on renvoie ce fameux maximum, qui est maintenant le maximum du tableau tout entier.

Ce texte constitura les commentaires de votre code. Il ne reste plus qu'à intercaler le code là où c'est nécessaire. Attention, rappelez-vous d'écrire le code le plus clair possible : ce n'est pas parce que l'on commente que l'on peut se permettre de s'écarter des bonnes pratiques de programmation. Il ne vous reste alors plus qu'à supprimer les commentaires faisant doublon avec le code, et à ajouter les délimiteurs / et /, pour obtenir :

int maximumTableau(int tableau[], int taille) {
			/* On parcrout le tableau, en gardant dans la variable
			maximum la plus grande valeur trouvée jusque là. */
			int maximum = tableau[0];	   
			int i;
			for(i = 1; i < taille; i++) {
				/* On met à jour le maximum si nécéssaire. */
				if(tableau[i] > maximum)
					maximum = tableau[i];
			}
			
			/* Enfin, on renvoie ce fameux maximum, qui est maintenant
			le maximum du tableau tout entier. */
			return maximum;
		}
		

J'ai choisi d'enlever la première phrase des commentaires vu qu'elle ne faisait que répéter ce que le prototype de la fonction disait déjà.

Bien entendu, mon exemple est éxagéré - sur un code aussi court et simple, il n'est pas forcément utile de mettre autant de commentaires. Il n'y a en outre pas grand chose à dire, en d'autres termes le code "parle de lui même". Le fait qu'il s'agisse d'un algorithme très simple et très classique joue aussi ; vu que le code est suffisament clair pour se passer de commentaires, on pourrait aussi bien tous les retirer ici.

Literate programming

La technique dont je viens de vous parler s'inscrit dans ce qu'on appelle la literate programming (à défaut d'une bonne traduction en français, je garderai le terme tel quel). Le concept principal est le suivant : au lieu d'écrire d'abord le code, puis les commentaires, ou bien d'écrire les commentaires au fur et à mesure que l'on code, on écrit les commentaires avant d'écrire le code.

Ainsi, au lieu de mettre les commentaires entre des marques spéciales (comme les /* et */ en langage C), et de considérer tout ce qui est à l'extérieur comme du code, on fait l'inverse : le code est inscrit entre des marques spéciales, et les commentaires sont constitués par tout ce qui est à l'extérieur.

Ce genre de commentaires sont utilisés dans une variante particulière du langage Haskell, qu'on appelle Literate Haskell. Dans ce langage, toute ligne ne commençant pas par le symbole '>' est un commentaire. Bien entendu, le symbole > en début de ligne marque un code. On peut ainsi obtenir des choses du style :

Cette fonction renvoie la plus petite valeur d'une liste.
	Pour cela, elle trie la liste avant de renvoyer le premier élément du résultat : on compose les fonctions de tri et d'extraction du premier élément.
	> minimum = head . sort

Ne vous inquiétez pas si vous ne comprenez pas tout de ce code ni du commentaire. L'important, ici, est que seule la dernière ligne, qui porte un marqueur spécial, est du code source : tout le reste est une simple explication.

Ainsi, on peut parfaitement imaginer un document écrit en HTML qui serait du Literate Haskell : le code HTML serait considéré comme du commentaire par Haskell, alors que le code Haskell sera considéré comme un texte banal par le navigateur web - ou tout autre programme qui lira du HTML. On peut par exemple se servir de cette caractéristique pour écrire un tutoriel que l'on peut soit lire - soit compiler, pour observer les exemples de code à l'œuvre.

Les générateurs de documentation

Il existe d'autres manières d'exploiter les commentaires d'un programme, et donc d'autres raisons d'y attacher un soin tout particulier. Par exemple, certains programmes peuvent, à partir des commentaires rédigés en une syntaxe spéciale, générer la documentation de votre code.

Pour ceux et celles qui l'ignoreraient, la documentation est la description de chacun des éléments de votre code : fonctions, classes, etc. Contrairement aux commentaires, qui sont lus par ceux et celles qui lisent ou modifient vos fonctions, la documentation est lue par ceux et celles qui utilisent vos fonctions, sans s'intéresser à leur fonctionnement interne.

Ainsi, il existe des générateurs de documentation qui parcourent votre code source, à la recherche de ces fameux commentaires spéciaux. Ils produisent alors la documentation de votre programme. Voici un exemple :

/** \brief Renvoie le plus grand élément d'un tableau d'entiers.
			 *  
			 *  @param tableau le tableau à analyser.
			 *  @param taille  la taille du tableau.
			 */
			int maximumTableau(int tableau[], int taille) {
			int maximum = tableau[0];	   
			int i;
			for(i = 1; i < taille; i++) {
				if(tableau[i] > maximum)
					maximum = tableau[i];
			}
			
			return maximum;
			}

J'ai ici rédigé mon commentaire afin qu'il puisse être compris par le logiciel Doxygen. Celui-ci va « savoir » que la fonction maximumTableau prendra deux paramètres, dont je lui ai donné la signification. Doxygen génèrera alors une jolie page HTML donnant le prototype de la fonction, ainsi que les explications que j'ai fournies dans le premier commentaire.

Il n'est pas nécéssaire de s'arrêter sur la syntaxe particulière exigée par Doxygen pour pouvoir générer la documentation, ce n'est pas le sujet. Vous avez vu encore une nouvelle utilisation des commentaires.

Conclusion

L'idée de base est que les commentaires doivent aider le lecteur et éviter de redire ce que le code dit. En vous montrant quelques utilisations possibles des commentaires dans un programme, j'espère avoir attiré votre attention sur l'importance des bons commentaires.

1 : Ici, « i » peut sembler incompréhensible, mais c'est le nom conventionnellement donné aux index dans les boucles for en C. Tout le monde le comprend très bien, on ne parle donc pas de « mauvais nom ».