CTO d’Azure : « Il est temps d’arrêter de démarrer de nouveaux projets en C/C++ »
(twitter.com/markrussinovich)- Si un scénario exige absolument un langage sans GC, utilisons Rust
- Pour la sécurité et la fiabilité
- Le secteur devrait déclarer C/C++ comme des langages deprecated
55 commentaires
Même parmi ceux qui vantaient Rust et l’utilisaient jusque-là, on dit qu’un gros retour à la réalité arrive dès qu’on se frotte à
async. Certains se plaignent même qu’on a l’impression qu’il ne faudrait pas créer de bibliothèques en Rust non plus tellement c’est complexe, pointilleux et difficile.Il y a même des gens qui le dénigrent sans savoir qui est Mark Russinovich... c’est l’auteur de la suite d’outils Sysinternals et du livre Windows Internals... c’est quelqu’un qui est devenu Microsoft Fellow après avoir fait du reverse engineering de Windows pour créer des outils...
Un billet qui se moque, via une courte vidéo, des problèmes des fans inconditionnels de Rust
https://twitter.com/cmuratori/status/1367627549816152064?lang=en
Rust n’a même pas encore de spécification officielle....
Le C++ a bien une spécification officielle qui « existe », mais toutes les implémentations (
gcc,clang, ...) sont incomplètes.C’est un raisonnement fréquent, mais pour avoir beaucoup lu de spécifications et tenté plusieurs implémentations, je ne vois pas très bien en soi ce que signifie le simple fait qu’il y ait ou non une spécification.
Il existe plusieurs stratégies de « spécification ». Il y a la méthode qui décrit principalement le comportement observable, et celle qui décrit le fonctionnement interne ; il y a aussi la distinction entre l’usage du langage naturel et des méthodes lisibles par la machine (pseudo-code ou définition mathématique, par exemple). Des documents comme la référence du langage Python ou de Rust sont des spécifications qui décrivent le comportement observable en langage naturel. L’approche qu’on voit souvent dans les normes ISO, etc., consiste à décrire le fonctionnement interne en langage naturel ; mais rien ne garantit que ce fonctionnement interne corresponde réellement à l’approche des implémentations existantes. À la place, on définit généralement la conformité au standard en disant que si une implémentation virtuelle fondée sur ce fonctionnement interne et une implémentation réelle ont, en apparence, le même comportement — c’est-à-dire qu’elles sont observationally equivalent — alors elles sont conformes au standard. ECMAScript est certes rédigé en langage naturel, mais sa structure réelle est en pratique proche d’un pseudo-code exprimé en langage naturel ; et il existe aussi des cas comme WebAssembly, qui fournit à la fois une spécification en langage naturel du fonctionnement interne et une définition mathématique.
Du point de vue de l’implémentation, les spécifications en langage naturel se valent plus ou moins toutes. Comme elles doivent être produites séparément de l’implémentation réelle, il est naturel que les deux puissent parfois diverger, et les erreurs y sont fréquentes. Le fait qu’il soit plus simple d’implémenter un comportement observable ou un fonctionnement interne dépend du contexte ; du point de vue d’un langage de programmation, il n’y a pas vraiment de raison impérative de choisir l’un plutôt que l’autre. En ce sens, Rust a déjà une spécification, et il est bien vrai que cette spécification fournit suffisamment d’informations pour permettre l’apparition d’autres implémentations.
Si vous souhaitez simplement juger de la maturité d’un standard au fait qu’il soit devenu ou non une norme ISO, je peux vous informer que j’ai trouvé environ 100 bugs dans la norme ISO/IEC 18181-1 JPEG XL (et que cela retarde pour cette raison le 2nd amendment)...
Il y a eu plus de 800 commentaires sur Hacker News aussi... Ici aussi, le débat est animé...
https://news.ycombinator.com/item?id=32905885
Merci pour votre travail.
Par ailleurs… j’ai trouvé juste ce texte qui disait que, lorsqu’on cherche à interpréter la réaction de quelqu’un quand quelque chose qu’il aime est attaqué, il faut se garder de l’attribuer à sa personnalité ; si j’ai trouvé cela pertinent, c’est sans doute parce qu’en situation réelle, il est difficile d’avoir un tel état d’esprit.
Il y a un commentaire de tweet assez marquant.
People end up writing Rust code the "unsafe way". - omis - Rust was never meant to replace those.
À ce stade, je joins un lien pour ceux qui veulent savoir qui est Mark Russinovich.
https://en.m.wikipedia.org/wiki/Mark_Russinovich
Je vais en rajouter une couche. Ceux qui, en utilisant C++, enchaînaient les erreurs et introduisaient des bugs, puis se sont dit : « Hé, on ne peut plus bosser avec ça, passons à Rust qui est à la mode ces temps-ci… On dit qu’on n’a plus à se soucier des erreurs mémoire… » — ces gens-là, c’est pareil. Ils finiront aussi par produire des bugs similaires avec Rust… Et ensuite ils seront nombreux à se demander quel langage apprendre pour essayer le suivant. Ce sont des gens qui, en C++, n’ont même jamais vraiment fait correctement une déréférence de pointeur, et qui encensent Rust.
Ce genre de personnes va ignorer tout ça — la propriété, les références, l’emprunt, que Rust met en avant comme points forts — parce que ça génère des erreurs dès la compilation et que c’est pénible à gérer, puis mélanger simplement de l’
unsafeet l’utiliser n’importe comment comme si c’était du C++.Puisqu’on va mourir de toute façon, pourquoi vivre ?
C’est à peu près le même niveau de logique que ça.
J’ai l’impression de voir l’argument selon lequel, puisque ceux qui causent des accidents ne mettent de toute façon pas leur ceinture et ignorent aussi les feux de signalisation, les ceintures de sécurité et les feux n’ont pas vraiment d’utilité.
On peut certes soutenir que les personnes compétentes réussiront quoi qu’elles fassent et que celles qui ne le sont pas échoueront quoi qu’elles fassent, mais si l’on suit cette logique, toute discussion sur l’utilité des outils devient impossible.
Le vrai problème, c’est que le langage est trop difficile à utiliser, donc oui, c’est un propos juste.
J’y croirai quand Visual Rust sortira... lol
On dirait vraiment que le C/C++ prend désormais le chemin du latin. Pour les études, tout le monde devrait l’apprendre, mais le maîtriser est presque impossible, et comme il s’agit d’un ancien système, il comporte aussi, à l’aune d’aujourd’hui, bien des aspects irrationnels...
C’est assez amusant de voir qu’on utilise sans problème des langages où tout est unsafe, mais qu’on affirme qu’un langage où l’on ne peut utiliser
unsafeque de façon limitée est absolument inacceptable.J’y vois une sorte de syndrome de Stockholm.
The Spirit of C
À mon avis, le point n°1 est déjà faux mdr, parce que les humains sont par nature sujets aux erreurs...
Avec C++, il suffit aussi d’utiliser activement les smart pointers et les memory pools...
Je pense qu’on a en réalité moins souvent qu’on ne le croit à manipuler directement des pointeurs.
Pour le code thread-safe, je pense qu’au final tout dépend des compétences du programmeur lui-même.
Quelle que soit la langue utilisée, si le niveau n’est pas bon,
on voit apparaître soit des performances médiocres malgré la sécurité, soit du code risqué.
Confier la conduite d'une voiture ou le pilotage d'un avion aux compétences d'un programmeur, c'est déjà bien trop effrayant....
Le code thread-safe relève au final des compétences du programmeur lui-même <- je trouve cette idée dangereuse, car la sûreté mémoire / thread safety ne se limite pas au fait qu’un programme plante ou ralentisse, elle peut évoluer en vulnérabilité de sécurité. Je pense donc qu’il ne faut pas laisser cela aux seules capacités d’un individu.
Divers moyens permettant de l’empêcher en amont ont été étudiés, et ils ont mûri au point de donner naissance à des langages comme Rust ou à d’autres outils. À mes yeux, l’impact des logiciels sur la vie quotidienne est devenu trop immense pour ne pas les utiliser et rejeter la faute sur les individus.
L’erreur est inévitable dès lors qu’on est humain, et même les programmeurs les plus brillants finissent par en commettre. Les bugs mémoire aussi, au fond, viennent d’erreurs...
Ces derniers temps, je me dis qu’au lieu de simplement compter sur le fait de bien faire, une meilleure approche serait peut-être de fournir dès le départ un environnement dans lequel il est difficile de se tromper.
Dans notre entreprise, si on veut utiliser Rust, l’usage de
unsafeest interdit. Il faut au moins une règle comme celle-là pour pouvoir se dire qu’on va vraiment faire confiance à la sûreté prise en charge au niveau du langage. Mais est-ce que c’est vraiment raisonnable ?Bien sûr, dans les entreprises qui utilisent Rust, il y a probablement un consensus selon lequel il ne faut pas utiliser
unsafesauf en cas de nécessité absolue. Mais je vous recommande plutôt d’essayer d’écrire directement en Rust... Vous ne saurez vraiment à quelle fréquence vous aurez besoin d’utiliserunsafequ’en l’ayant essayé vous-même, non ?Dans des bibliothèques bien connues comme
tokio, il y avait partout duunsafe.Il y a visiblement pas mal de commentaires qui considèrent les choses sous l’angle du tout ou rien, en estimant que si ce n’est pas « tout », cela n’a aucune valeur.
on peut distinguer et isoler explicitement
unsafeetsafe, et il y a l’avantage de pouvoir faire passer quelqu’un qui produirait 100 bugs mémoire à seulement 10. Pourtant, l’approche qui consiste à dire : de toute façon,unsafeexiste / donc des bugs mémoire se produisent quand même => par conséquent, il n’y a rien de mieux que C++ — je ne suis pas vraiment sûr que ce soit une manière réaliste de juger les choses 😅En nombre de commentaires, c’est bien le cas, mais...
On dirait plutôt qu’une seule personne, avec une opinion du type « tout ou rien », a écrit beaucoup de commentaires... et que c’est ça, la vraie situation.
Je suis moi aussi d’accord avec ce commentaire. Plus on voit les choses de manière binaire, plus on se pénalise soi-même.
Dans le travail réel, on finit par choisir ce qui présente au final le plus d’avantages après avoir pesé le pour et le contre.
Compte tenu des spécificités du secteur, si l’on n’est pas dans une situation où l’on n’a pas d’autre choix que d’utiliser C/C++ pour le moment, je pense que les bénéfices obtenus en utilisant Rust sont importants, et que c’est pour cela que les domaines où Rust est utilisé s’élargissent progressivement.
Les gens qui passent à Rust ne sont pas idiots non plus ; s’ils continuent à l’utiliser, c’est bien qu’après l’avoir essayé, ils y trouvent au final des avantages supérieurs à ceux de C++, haha.
Rien... Tout
Il est désormais rare de trouver quelqu’un qui ne soit pas d’accord pour dire que Rust est le prochain C++. Après tout, il a même été adopté comme langage officiel dans le noyau Linux.
Cela dit, on peut se demander si Rust est vraiment un langage pratique à utiliser... À cause de l’analyse statique effectuée pour prévenir en amont les problèmes de sécurité mémoire, les temps de compilation sont assez pénibles, et des sémantiques comme l’ownership sont difficiles, si bien qu’il demande bien plus d’apprentissage que des langages généralistes comme Python ou Java.
Le temps de compilation vient probablement surtout de LLVM lui-même. Facebook s’efforce d’améliorer l’instruction selection de LLVM, donc la situation devrait s’améliorer.
En regardant, c’est vraiment le cas. Je pensais qu’on passait surtout beaucoup de temps sur les vérifications de types liées à l’ownership, mais le backend LLVM est énorme...
Quand Rust est apparu au début, je m’y suis beaucoup intéressé et je l’ai un peu étudié... puis j’ai vu la partie
unsafeet j’ai immédiatement laissé tomber. Je n’ai vraiment pas réussi à me convaincre rationnellement pourquoi il faudrait apprendre ça pour l’utiliser. De toute façon, dès qu’un programme devient un peu complexe, il faut bien utiliserunsafe. Et dans ce cas, la sécurité dont Rust se vante tant disparaît. Pourquoi utiliser ça ?Dans Rust, on peut considérer qu’
unsafen’est nécessaire que pour le codage bas niveau, et qu’on n’a quasiment jamais besoin de l’utiliser pour écrire des applications classiques.Et même si un problème mémoire survient dans un bloc
unsafe, le langage garantit que la partie en cause se trouve à l’intérieur de ce blocunsafe, ce qui a aussi l’avantage de faciliter le débogage.S'il y a
unsafeet que vous demandez « pourquoi utiliser ça ? », alors il ne faudrait pas utiliser le C/C++ dès le départ, non ?Le C++ continue lui aussi d’évoluer, et quitte à utiliser de l’unsafe, autant utiliser directement du C++ ; je ne ressens pas vraiment la nécessité d’apprendre Rust pour l’utiliser.
Tous les programmes Rust n’ont pas besoin de
unsafe.Les manipulations mémoire suffisamment délicates pour nécessiter
unsaferelèvent généralement du développement de bibliothèques, donc côté développement applicatif — là où la demande sera probablement la plus forte — je pense qu’on aura rarement à utiliserunsafe.C++ continue certes d’évoluer, mais l’héritage legacy pour assurer la rétrocompatibilité est vraiment lourd. Si
unsafeà lui seul vous dérange à ce point, j’ai l’impression que toutes les fonctionnalités de C++ doivent vous déplaire aussi hahaC’est pour ça que
unsafen’est pas recommandé.Si on utilise
safe, tout est plus sûr que le C/C++, où tout revient plus ou moins à êtreunsafe.https://people.mpi-sws.org/~dreyer/papers/rustbelt/paper.pdf
Sans ce mécanisme ambigu qu’est
unsafe, Rust pourrait peut-être devenir une véritable alternative au C++.J’aurais aimé que la FFI soit un tout petit peu plus conviviale… J’ai le souvenir d’avoir énormément souffert quand j’ai essayé d’échanger des structures composites avec une bibliothèque externe via la FFI.
Même du Rust vers Rust, ce n’est pas si simple non plus..
https://github.com/rodrimati1992/abi_stable_crates
Dans le contexte du soutien actif de Microsoft à Rust, cette déclaration semble tout à fait naturelle.
Même le têtu Torvalds a adopté Rust, donc je ne vois pas vraiment l’intérêt de continuer à utiliser un langage que de moins en moins de gens apprennent.
Les bugs liés à la mémoire ne disparaîtront jamais simplement parce qu’on utilise Rust. Les humains qui créent des bugs en produiront quel que soit le langage qu’on leur donne. On utilise très bien C++ efficacement et sans aucun problème, alors le supprimer, de quoi parle-t-on ? Il a vraiment lâché une déclaration explosive, comme si on était en temps de guerre.
Il est difficile de dire qu’on utilise C/C++ efficacement et sans aucun problème : historiquement, d’innombrables bugs liés à la mémoire ont éclaté en C/C++, et il y en a probablement encore qui se produisent quelque part en ce moment. (Cela dit, grâce à eux, beaucoup de chercheurs en PL/SE ont pu gagner leur vie.)
Selon l’annonce de Microsoft, 70 % des bugs de sécurité sont liés à la mémoire (https://zdnet.com/article/…)
L’enquête menée par le projet Chromium allait dans le même sens (https://www.chromium.org/Home/chromium-security/memory-safety/) : là aussi, près de 70 % étaient des bugs liés à la mémoire.
J’avais lu quelque part, dans un ancien article, que la plupart des bugs du noyau Windows étaient des erreurs liées à la mémoire, et que, sur les parties développées en Rust, ces erreurs avaient fortement diminué.
Comme le langage, par sa conception même, encourage activement le
readonly, il me semble difficile de nier que sa conception est plus sûre que celle du C++. En contrepartie, cela introduit ce concept de propriété, sorti de nulle part pour beaucoup, qui rend la programmation plus difficile.Il y a aussi l’avantage en matière de performances : statistiquement, du code Rust bricolé à la va-vite s’exécute plus vite qu’un code C++ pourtant très bien conçu.
Il a dit quelque chose qui risque de faire réagir, haha.
Personnellement, je trouve que C++ est tellement ancien qu’il est freiné par la compatibilité descendante, ce qui ralentit son évolution vers quelque chose de plus moderne.
Et comme on ajoute des éléments modernes tout en préservant rigoureusement la compatibilité descendante, il y a beaucoup trop de façons différentes de faire la même chose, ce qui constitue selon moi une barrière à l’entrée supplémentaire pour les débutants.
Moi aussi, je pense désormais que Rust vaut mieux que C++. L’époque où on se ruinait les yeux à traquer des bugs liés à la gestion mémoire, c’est terminé.
Oui, c’est vrai… S’il s’agit d’un projet de développement lancé de zéro, il n’y a pas vraiment de raison de choisir le C++.
Je suis tellement d'accord
Même si j’ai envie d’utiliser Rust, pour le travail il n’y a encore guère d’occasions de l’utiliser autrement qu’en complément.
Du coup, j’ai du mal à vraiment m’y habituer, et dès que je le laisse de côté un moment, j’oublie tout...
J’ai clairement envie de l’utiliser parce que ça me plaît, mais... haha
Ceux qui n’ont même jamais essayé d’écrire un pool mémoire pour améliorer l’efficacité d’utilisation du tas se mettent à radoter sur Rust, putain haha
Le CTO d’Azure n’est évidemment pas une opinion qui représenterait à ce point le standard de l’industrie, et même en se limitant à Microsoft, ce n’est absolument pas une opinion qui parle au nom de Microsoft ; ce n’est peut-être rien d’autre qu’un type qui, pris soudainement d’une lubie, déballe simplement son avis subjectif… Ceux qui ne savent même pas faire correctement du C++, ils vont vraiment mieux s’en sortir avec Rust ? Bref, c’est encore rempli de grandes gueules qui racontent n’importe quoi.
Votre façon de parler révèle sans la moindre ambiguïté une vulgarité affligeante. Bon courage.