Les trois types de développement

Article original : The three types of development | Belay the C++ (belaycpp.com)
Traductrice : Chloé Lourseyre

Cette semaine nous allons discuter d’un sujet sérieux qui concerne la communauté de développeurs. Cela peut toucher plusieurs langages, mais le C++ est un des plus concernés par cela1.

Il y a plusieurs « manières » de développer en C++. Par « manières », je veux dire un ensemble de contraintes et de circonstances qui vont affecter ce que vous pouvez faire, ce que vous devez faire et comment vous faites ces choses.

Cela peut sembler vague, mais vous pouvez considérer que ce sont des types d’environnement qui peuvent drastiquement changer votre approche du code que vous lisez, modifiez, écrivez.

En me reposant sur mon expérience, j’ai réussi à détacher trois types de développement2.

Les trois catégories

Le développement (quasiment) solo

C’est le type de développement qui a le moins de contraintes (sinon aucune). Quand vous développez seul·e ou avec peu de collaborateurs, vous pouvez librement choisir ce que vous voulez faire et comment vous allez le faire.

Le développement collaboratif sous licence

Si vous êtes sur un plus gros projet, vous pouvez voir des contraintes apparaître. La plupart du temps, ces contraintes seront axées sur quelles librairies vous pouvez utiliser ou pas.

Par exemple, si vous voulez vendre votre logiciel, vous ne pouvez pas utiliser de librairie qui est sous la licence JRL, car elle interdit les utilisations commerciales.

C’est un type de développement qui concerne principalement les petites entreprises et les développeurs indépendants.

Le développement industriel

Certains projets sont lancés par des grosses entreprises ou groupes d’entreprises. Ils peuvent être en développement pendant plusieurs années (voire même décennies si on compte la phase de maintenance), mais surtout ils doivent respecter de lourdes contraintes à propos de quelles librairies vous pouvez utiliser et sur l’intégralité de l’environnement de développement.

C’est typiquement sur ce genre de projet qu’on utilise les plus vieilles versions du C++ (souvent antécédentes au C++17, parfois même en C++03). C’est souvent parce que c’est la hiérarchie (et non les développeurs eux-mêmes) qui pilotent le budget de ce genre de projet et décident si l’environnement doit être migré ou pas.

Beaucoup de développeurs qui travaillent sur ce genre de projet arrivent au milieu de celui-ci et font face à une résistance tenace quand ils essayent d’améliorer l’environnement de développement3.

Dans ce genre de situation, vous avez souvent affaire à du code existant (du legacy code) ou à une part de la codebase que vous ne pouvez tout simplement pas modifier4.

Qu’est-ce qui est spécifique au C++ ?

Le C++ est un langage complexe, pas seulement par sa syntaxe et les spécificités qui lui sont propres, mais aussi parce qu’il y a des centaines (sinon des milliers) d’environnement différents possibles.

Il y a des dizaines de compilateurs pour le C++, portés sur un nombre important de systèmes d’exploitation. Aujourd’hui, il existe 5 versions différentes du standard5 qu’on peut rencontrer des projets professionnels.

Il est donc essentiel pour chaque développeur C++ d’adapter son discours à la personne adressée. En effet, en fonction des circonstances et des particularités de chacun, vous pourrez être amené·e à dire une chose ou son contraire.

Terrains d’affrontement

Il existe un endroit où les trois types de développement peuvent être représentés en même temps : internet. Quand vous rôdez sur les forums dédiés, vous finirez fatalement par rencontrer des gens qui sont actuellement en train de travailler sur un projet d’un type différent du vôtre.

Dans l’absolu, c’est une bonne chose que les développeurs venant d’horizons différents puissent échanger sur le C++, mais cela peut mener à des problèmes de communication.

En effet, si un développeur – qui n’a jamais réalisé qu’un seul type de développement – essaye de donner des conseils ou de faire des commentaires à un développeur venant d’un autre type de projet, une part importante de ces conseils et commentaires risque de ne pas prendre en compte les contraintes et circonstances spécifiques, et ainsi être inutile.

Prenons quelques exemples pour illustrer cela.

Exemple provenant de r/cpp

Le premier exemple vient de Reddit, plus spécifiquement du subreddit r/cpp :

Je ne suis pas spécialement convaincu·e par cet argument. Tous les compilateurs C++ modernes génèrent des warnings si les arguments du printf ne correspondent pas à la chaîne formatée, même si l’API elle-même ne force pas ce fait.

Oui, ça t’oblige à activer -Wall mais honnêtement tu devrais toujours avoir les warnings de compilation activés.

Ce commentaire est typique : bien que courtois, il est à côté du sujet en se basant sur deux sophismes :

  • « Tous les compilateurs C++ modernes génèrent des warnings […] ». Cela dépend beaucoup de ce qu’on entend par « moderne », mais au-delà de ça il existe beaucoup de compilateur qui ne fonctionnent pas comme les compilateurs standards parce qu’ils répondent à des besoins spécifiques. Je pense en particulier aux compilateurs visant des systèmes embarqués, des microcontrôleurs, les compilateurs expérimentaux ou encore les compilateurs faits-maison conçus pour certains projets particuliers ou encore tout simplement des compilateurs un peu âgés qui ne l’implémentait pas à l’époque où ils ont été distribués. Essayer de généraliser, dans ce contexte, est fallacieux, surtout entendant que « l’API elle-même ne [le] force pas« .
  • « […] honnêtement tu devrais toujours avoir les warnings de compilation activés. ». C’est une phrase que j’entends souvent et je pense que celles et ceux qui la prononce n’ont jamais travaillé sur un projet de taille industrielle. Notre travail (en tant que vétérans du C++) est d’essayer de changer les mentalités en mieux, mais parfois (sinon souvent) cela peut ne pas marcher, malheureusement. Il y a également des situations où vous arrivez sur un projet et vous constatez qu’il y a des centaines et des centaines de warnings déjà présents. Dans ce cas, la hiérarchie ne vous donne que très rarement la possibilité de les corriger et, dans ce genre de contexte, la chasse aux warnings est une cause perdue.

Bien sûr, on devrait toujours essayer de changer le monde pour le meilleur et essayer de détruire les environnement de développement inadéquats, mais nier leur existence c’est nier une part de la réalité, réalité que nous sommes beaucoup à vivre quotidiennement.

Quand cela arrive, essayez de nuancer vos propos, laissez votre pensée ouverte pour que vos interlocuteurs puissent y préciser leurs conraintes.

À la place de dire

« Oui, ça t’oblige à activer -Wall mais honnêtement tu devrais toujours avoir les warnings de compilation activés. »

Dites plutôt

« Si tu peux activer -Wall tu devrais parce que ça t’aidera à surmonter cette problématique et bien d’autres encore. »

Exemple provenant de Stack Overflow

Voici un second exemple, issu de Stack Overflow :

Mon meilleur conseil serait de ne pas écrire de macro comme ça. Pourquoi tu as besoin d’utiliser __LINE__ ?

Un commentaire court, mais il y a beaucoup de choses à en dire.

« Mon meilleur conseil serait de ne pas écrire de macro comme ça ». D’accord, mais pourquoi ? À cause du fonctionnement intrinsèque des macros ? Parce que je ne pourrai pas atteindre mon objectif avec ? Parce que les macros sont fondamentalement mauvaises et qu’il existe une alternative fonctionnelle ?

La question originale pose la contrainte suivante :

FOO et FOO_END doivent être des macros. C’est parce que j’ai besoin d’utiliser __LINE__ et __FILE__ en leur sein.

Sachant cela, est-ce que la question « Pourquoi tu as besoin d’utiliser __LINE__ ? » est vraiment pertinente ? Puisque le post se base sur cette contrainte, que tu saches ou pas pourquoi l’utilisateur a besoin de __LINE__ ne t’aidera pas à l’aider6.

Écrire un commentaire pertinent est simple quand on y réfléchit un peu. Par exemple :

Ce commentaire précise très simplement que les pointeurs sont dans la plupart des cas à éviter, tout en admettant qu’il existe des situations dans lesquels ils sont nécessaires. Il a été écrit pour sensibiliser l’utilisateur original aux problématiques que peuvent cause les pointeurs tout en restant pertinent.

En conclusion

Quand vous voulez aider les autres développeurs, vous devez absolument faire attention aux circonstances qui les contraignent. Votre réponse n’atteindra pas sa cible si vous n’êtes pas pertinent·e.

De plus, vous devez vous poser la question suivant : aidez-vous qui que ce soit si votre conseil pourrait se résumer à « Tu dois changer d’environnement de développement » à quelqu’un qui ne peut ou veut pas en changer ? Vous devez vous adapter à ces situations, mettre vos paroles en perspective, pour que votre interlocuteur·ice retienne votre conseil, même s’iel ne peut pas l’appliquer dans son cas précis.

Il est très facile de tomber dans le sophisme et l’argument d’autorité. Essayez toujours d’expliquer vos arguments, même si ça vous semble trivial ou « de bon sens ». Cela leur donnera du poids. Et si jamais vous n’arrivez pas à expliquer simplement et clairement vos arguments, il y a une (très) forte chance pour qu’ils soient, en réalité, fallacieux.

Merci de votre attention et à la semaine prochaine !

Article original : The three types of development | Belay the C++ (belaycpp.com)
Traductrice : Chloé Lourseyre

Addendum

Notes

  1. Dans cet article, j’utiliserai le C++ pour illustrer, mais tout ce qui sera dit peut être applicable à n’importe quel langage de programmation. J’expliquerai plus tard dans l’article les spécificités inhérentes au C++.
  2. Selon votre propre expérience, vous pouvez découvrir d’autres types de développement. Ceci s’ajoutent naturellement à ceux présentés ici.
  3. La définition du terme améliorer est fondamentale ici. Ce qu’un jeune développeur sur un projet considère comme étant une amélioration n’est pas la même chose que ce qu’un développeur chevronné, un responsable, un commercial ou un client peuvent considérer comme une amélioration. « C’est très bien que tu ais passé une année complète à mettre à jour la codebase en C++20, avec un nouveau GCC et clang, mais tu n’as corrigé ni reporté aucun bug, ni implémenté une des nombreuses fonctionnalités promises au client, et en plus maintenant on ne peut plus maintenir le code legacy… ».
  4. Par exemple : parce qu’elle appartient à une autre équipe ou entreprise, parce qu’elle a déjà été livrée au client, ou encore parce qu’elle a été validée par la QA et qu’il faudrait des semaines pour la faire revalider.
  5. Je compte seulement à partir du C++03 (donc C++03, 11, 14, 17 et 20) vu que le C++98 es très similaire au C++03.
  6. Il peut arriver que l’utilisateur original ait fait mention de contraintes qu’il pourrait en fait contourner. Mais ce n’est pas pour autant constructif de le « babysitter », il faudrait par exemple lui proposer des alternatives avec des exemples à la clé.

Laisser un commentaire