Je ne connais pas assez le contexte pour me prononcer, je me demande pourquoi un pointeur et pas une référence par exemple.
Plus généralement, il est des situations où donner une indication du type dans le nom de la variable rends le code plus clair (exemple: quand plusieurs types sont capables de représenter la même info et qu'on en a besoin simultanément; mais même alors ce n'est pas tant le type précis qu'on utilise qu'une information d'un peu plus haut niveau comme la bibliothèque qui le fournit. Si on reprend ton exemple plus haut, avoir comme variable name de type std::string et cName de type char const* par exemple plutôt que ton szName).
Mais ce avec quoi je ne suis pas d'accord, c'est l'utilisation systématique de la technique sans bonne raison. Je ne vois pas du tout l'intérêt de préfixer par p toutes mes variables d'un type dont on ne manipule jamais que des pointeurs.
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.
Cette dernière remarque me fais penser à un truc: faudrait-il nommer ses variables en fonction du contexte?
Par exemple, cette histoire de noter différemment une variable passée en paramètre. J'ai travaillé récemment sur un projet où cela faisait partie de la convention de nommage. Par exemple:
Et je me suis rendu compte que dans le cas de grosses fonctions (typiquement un algorithme un peu long, ou une fonction qui utilise une API en C et qui contient un gros switch) c'est assez agréable: on n'a pas besoin de remonter à la signature de la fonction pour savoir d'où viens cette variable.
Code : Sélectionner tout - Visualiser dans une fenêtre à part void MaFonction(int p_UnInt)
Idem pour les pointeurs. Il y a des cas où ça peut être intéressant de le spécifier dans le nommage.
La bonne solution serait-elle donc de faire une convension "adaptative"? Ou, au moins, assez souple, dans le sens ou l'on permettrait plusieurs notations différentes dans certains cas.
Est-ce complètement farfelu ce que je dis là?
« L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
Spinoza — Éthique III, Proposition VII
je pense que de base trackIndex est un mauvais nom pour une variable pointeur. ce n'est sans doute pas un index. ce que je veux dire par la c'est que le fait que c'est un pointeur et pas un entier est en general refleté dans le nom de la variable, car elle a un but different. on a donc tous plus ou moins tendance a differencier un pointeur de sa variable pointée, ne serait-ce que car on ne les utilise pas pareil.
Si par exemple tu te sers de cellCursor qui est de type cell*, le fait que c'est un pointeur est impliqué dans le "cursor". tu t'attends a faire des ++ et des -- dessus pour deplacer le curseur.
Si tu n'as pas de nom pertinent, alors au lieu d'appeler pCell pour "un pointeur sur une cellule" peut etre vaut il mieux reflechir a un nom plus explicite.
Pour moi la covention de nommage, a part indiquer l'origine de la variable (champ de classe, globale ou bien locale ou parametre) ca montre un echec de donner un nom correct a une variable.
c'est bien beau de donner des lecons car je sais tres bien que mon code est rempli de variables au noms obscurs qui ne font pas ce qu'elles disent faire, mais autoriser la convention de nommage c'est autoriser les gens a appeler leurs variables pCell pour un pointeur sur cellule sans dire ce que ca fait. enfin les gens en profiteraient pour ne pas mettre de nom, en disant que c'est un pointeur sur une cellule.
7 lignes pour une methode, c'est vraiment rikiki quand meme... on s'autorise un ecran nous, tout doit tenir dans l'ecran, soit une 60aine de ligne.
nos fonctions sont aussi aerees, on ne colel pas plusieurs instructions sur la meme ligne. de plus on utilise les accolades chacune sur une ligne separee.
je ne peux meme pas faire un if-else dans ta fonction de 7 lignes...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 // 8 lignes if(test) { call(1); } else { call(2); }
Il y a plein de raisons en C++ d'utiliser un pointeur vers une variable qui contient un indice de piste (trackIndex). Puisque la discussion porte sur le nommage et pas sur l'utilisation de tel ou tel type de référence/pointeur/itérateur/curseur/etc, l'argument que je présente est qu'il est plus confortable d'avoir l'info qu'il s'agit d'un pointeur et pas de la variable elle-même.
En l'occurrence, c'est exprès que je n'ai donné aucun contexte pour mes deux variables: dans la pratique, c'est ce qui se passe chez le lecteur. Exemple: on regarde une ligne, on en discute, on va voir un peu ailleurs, puis on y revient et on passe à la suivante. Toc, voilà une affectation de pointeur, et c'est bien de ne pas avoir à remonter à la définition de la variable pour se la remémorer.
J'ai donné mes conventions à titre d'exemple, et elles viennent à 90% de mon jugement esthétique et de mon expérience. J'en suis très satisfait, et n'ai jamais trouvé de raison de ne plus les appliquer - j'en ai, par contre, éliminé bien d'autres par le passé.
Jean-Marc, si elles sont systématiques, c'est parce que cela diminue l'intellectual overhead, comme ils disent chez eux. Je préfère réfléchir à ce que je fais de mon pointeur plutôt qu'à si je dois lui donner un "p" ou pas.
Si d'autres utilisent d'autres conventions, je les invite à les proposer, pour que ceux qui sont en recherche de la leur aient plusieurs choix. Mais la mienne marche bien pour moi, je la garde, merci!
Carl
Skreetch, fournis d'autres exemples, cela m'aidera à comprendre ton point de vue. Nous sommes déjà d'accord sur "p" ou "cursor" (que je considère comme équivalents, probablement à cause de la dualité du rôle des pointeurs). Tu as d'autres cas?
Carl
C'est pas réellement des lignes au sens retours chariot, plus des lignes au sens NCSS (Non Commenting Source Statement, cf. par exemple CppNcss).
MAT.
Amusant, l'argument de l'intellectual overhead marche pour moi dans l'autre sens. J'ai assez souvent à lire du code écrit avec une convention proche de celle que tu indiques (une donnée membre pointeur sur un objet sera écrite m_poTruc, un paramètre de fonction pointeur sur un objet p_poTruc...).
Et quand je lis ce code, je me suis rendu compte que je fais justement une première passe mentalement qui consiste à ôter les "préfixes inutiles qui encombrent l'écran et la mémoire" afin de ne garder que la substantifique moelle de la fonction, quelle variable va où, ce qu'on lui fait, ce qu'on attend d'elle. Jamais ce préfixe ne m'a apporté la moindre information utile quand je lis du code, il n'est qu'un bruit pour moi, et j'ai donc appris la gymnastique mentale pour l'ignorer et me concentrer sur le signal.
Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.
Un bon nom dépend du contexte, c'est certain. Est-ce qu'il faut rentrer
trop dans les détails dans les conventions de codage? je n'en suis pas
sûr. Ca demanderait énormément de travail de spécification pour un
résultat qui sera incomplet presque par définition. Et après certains ont
tendance à considérer les conventions comme la lettre de la loi -- et donc
n'admettre aucune déviation aussi justifiée soit elle. Et d'autres ne vont
même pas prendre la peine de lire un document aussi complexe -- il n'aura
de sens quasiment que pour ses auteurs.
Sur le principe, je suis d'accord. Sur la valeur donnée: tu m'écris une
fonction qui fait la division de deux nombres en précision arbitraire en ne
dépassant pas cette valeur et on en rediscutte.
J'ai beaucoup de mal à discutter du choix d'un nom sans en comprendre le
contexte un minimum. Hors, c'est bien de ça dont il s'agit: le choix d'un
nom. Et j'ai également beaucoup de mal à comprendre une ligne de programme
sans son contexte, et ce d'autant plus qu'il s'agit d'une modification de
variable -- on peut comprendre un programme purement fonctionnel avec peu
de connaissance du contexte, pas un programme impératif (c'est l'argument
principal des tenants du tout fonctionnel). Donc, si je tombe sur une
affectation sans connaître le contexte, j'en prend connaissance avant tout.
Des noms plus longs, c'est des lignes plus longues, donc un obstacle à laJean-Marc, si elles sont systématiques, c'est parce que cela diminue
l'intellectual overhead, comme ils disent chez eux. Je préfère
réfléchir à ce que je fais de mon pointeur plutôt qu'à si je dois lui
donner un "p" ou pas.
lisibilité (il faut les couper plus souvent, ce qui est aussi un problème
intéressant).
Et comme je l'ai écrit, si parfois une indication sur le type est utile
dans le nom, je ne suis pas sûr que ce soit sur la qualité de pointeur
qu'il faille insister.
Ce n'est pas parce qu'une règle est facile à appliquer et qu'elle évite des
problèmes dans certains cas qu'elle est la meilleure solution à ces
problèmes et qu'elle n'est pas nuisible dans d'autres cas.
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.
Je ne vois pas le rapport avec l'algorithme ou le contenu en lui-même...
On peut décomposer n'importe quelle fonction/méthode en plein de méthodes d'une seule ligne/statement (edit : une ou deux lignes en fait), c'est pas vraiment un problème technique sur comment procéder (il suffit de répéter le remaniement extract méthod), c'est plutôt de savoir où s'arrêter pour rendre optimale la (re)lecture pour la maintenance.
Plusieurs études sur la mémoire à court terme sortent ce chiffre de 7(+/-2), on le retrouve notamment sur la page de wikipedia short term memory, qui, même si les conséquences qu'on peut en tirer ont été nuancées depuis les premières études (années 50), à l'usage s'adapte particulièrement bien.
Bien sûr si une fonction fait 12 lignes/statements c'est pas non plus la fin du monde...
MAT.
je suis d'accord avec jean marc, se fixer des contraintes ainsi c'est diminuer la complexité locale mais augmenter la complexité locale. surtout car 7 lignes c'est vraiment rikiki.
Augmenter la complexité globale tu veux dire ?
Le truc c'est que bien sûr on ne coupe pas pour le plaisir de couper mais un peu intelligemment pour illustrer l'algorithme qu'on découpe (dans le choix des noms des sous-méthodes notamment).
Le but c'est tout à fait de diminuer la complexité des méthodes pour reporter ça au niveau au-dessus. Ensuite on reproduit la même chose au niveau des classes (pas plus de quelques méthodes, par exemple 5 ou 7 pour donner un ordre de grandeur encore une fois), ce qui a pour effet de remonter de nouveau la complexité au(x) niveau(x) supérieur(s).
Et on obtient beaucoup de classes simples (tellement simples que souvent on n'a même plus besoin de les tester unitairement) que l'on assemble et compose pour obtenir son système/application.
Pour moi c'est aussi ça le développement orienté objet : repousser la complexité au niveau des objets...
MAT.
Je dirai plutôt que la complexité est dans l'implémentation, pas dans les fonctions membres. Quand tu es client d'une classe, la seule chose que tu vois, c'est l'interface publique, qui doit effectivement être simple. Mais ça n'empeche pas la classe d'utiliser des méthodes très compliquées...
"transpose" ? Je ne te suis pas.
A tout hasard, je précise ma pensée. Je réagissais à la remarque de Loïc comme quoi le système de types du C++ nous offre un autre moyen de s'y prendre. Chose que je reconnais vrai, mais que je trouve inusitée -- et en fait impossible à exiger (lourd, ...).
D'où que l'alternative du rwMax colMax (exposée dans l'article) est pas plus mal que cela. Certes, aucune technique ne prévient contre toutes les erreurs.
Pour ta remarque concernant l'Ada, ce langage commence à être un peu loin pour moi. Les sous-types y étaient plus fortement typés que les typedefs en C++, ou pas?
Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...
Calcule la transposee de ta matrice. Exemple le plus simple auquel j'ai pense ou on a besoin d'inverser les indices. Juste un signe supplementaire de lourdeur.
Je suis d'accord avec toi. Je ne faisais que pointer une des difficultes que pousser trop loin l'utilisation du typage introduit et indiquer que meme dans un langage ou il est coutumier d'introduire beaucoup plus de types qu'en C++, ca ne se faisait pas dans mon environnement (c'est toujours difficile de pretendre que ca ne se fait pas dans l'absolu).A tout hasard, je précise ma pensée. Je réagissais à la remarque de Loïc comme quoi le système de types du C++ nous offre un autre moyen de s'y prendre. Chose que je reconnais vrai, mais que je trouve inusitée -- et en fait impossible à exiger (lourd, ...).
D'où que l'alternative du rwMax colMax (exposée dans l'article) est pas plus mal que cela. Certes, aucune technique ne prévient contre toutes les erreurs.
Intermediaire.Pour ta remarque concernant l'Ada, ce langage commence à être un peu loin pour moi. Les sous-types y étaient plus fortement typés que les typedefs en C++, ou pas?
Il y a des conversions implicites entre les sous-types d'un meme type et avec le type de base. (Mais si j'ai bonne memoire -- c'est loin pour moi aussi -- on peut surcharger sur des sous-types).
Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.
Bon je n'ai pas encore lu le thread en entier mais...
mes 2 cents :
Lorsque j'ai intégré ma boite, j'ai du me faire à une convention "maison" qui ressemble à la hongroise, mais en encore plus pervers :
i_Integer
l_Long
sz_CharEtoile
str_String
o_Object
o_mMemberObject
i_gGlobal
sz_fFunctionThatReturnsACharEtoile
l_pPointeurSurLong
Bon, je vulgarise le langage mais vous avez compris l'idée.
Et bien sachez que je n'approuve pas du tout ces conventions
Bon je n'ai pas le choix je fais avec mais ca m'énerve passablement.
J'ai également lu dans un bouquin "Standard de programmation en C++" [Herb Sutter & Andrei Alexandrescu] que la convention que l'on choisi ne doit pas être trop contraignante car on finit toujours par la transgresser à un moment ou à un autre. Et je trouve cette remarque assez vrai.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager