Quelques raccourcis :
Notez que le contenu de cette page est en chantier, en particulier sur le plan du formatage, car je suis débordé. Je retravaillerai le tout dès que possible, promis.
Grâce à l'Université de Sherbrooke (en particulier, grâce à Jean Goulet et à Claude Cardinal du CeFTI) et au Collège Lionel-Groulx (en particulier à Éric St-Jean et à mes collègues du département d'informatique), j'ai le privilège de participer à CppCon 2018.
Ce qui suit est une sorte de journal de voyage, avec éléments humains et éléments techniques.
Notez que j'ai eu une semaine très, très occupée, et que j'ai assurément oublié de mentionner plusieurs rencontres. Si je ne vous ai pas mentionné, ça en dit plus sur ma mémoire défaillante que sur l'intérêt que je vous ai porté.
Quelques termes que vous verrez ci-dessous :
Pour un peu de bagage supplémentaire sur l'événement, voir :
Pour les journaux de voyage d'autres participants, voir :
Début du contenu technique
Je vais mettre le contenu technique dans des blocs les mettant comme celui-ci. Si vous ça ne tombe pas dans vos cordes, passez par-dessus.
Fin du contenu technique
Commençons par les choses les plus sérieuses : j'aime ma femme et mes enfants. Mes voyages des dernières années sont intéressants, je rencontre des gens passionnants et je suis chanceux de vivre ce que je vis et j'en suis reconnaissant (même si j'ai travaillé fort avant d'avoir ce privilège), mais reste que chaque fois que je pars, je laisse le coeur de ma vie derrière moi. Za, je t'aime.
Nous sommes vendredi et c'est une journée chargée pour moi. Cette journée commence par les enfants qui souhaitent des crèpes (que je fais avec plaisir), suivi d'un trajet vers une (excellente) pension pour chiens, où nos chiens passeront quelques jours (pas la totalité de mon voyage, mais quelques jours), puis je suis allé enseigner au Collège de 8 h à 9 h 45. Retour à la maison ensuite pour ficeler mes bagages. Il pleut abondamment, et on annonce un après-midi très venteux; je ne veux pas revivre l'expérience de 2016, où mon vol vers Seattle a été... compliqué.
Mon papa Réal vient me chercher et m'amener à l'aéroport (merci!), où je passe les fouilles beaucoup plus aisément qu'à l'habitude. Faut savoir que mes fouilles sont typiquement longues, car il y a de la poudre de craie sur mon ordinateur portatif (enseignement aidant) et les douanières comme les douaniers trouvent cette poudre blanche suspecte apparemment.
J'ai trouvé un endroit où il y avait un wrap pas mal du tout (thon, poivrons, câpres), que je suis allé manger près de mon point d'embarquement tout en travaillant. L'aéroport semble avoir été rénové, c'est joli.
Je parviens à travailler en attendant l'avion, et j'apprends de mon directeur de thèse Bessam que la date de ma défense de thèse, en octobre, semble se préciser, les gens du jury ayant commencé à choisir des dates possibles dans la liste de celles que nous leur avons proposées. J'écoute Dans les médias, toujours excellent, en prenant mes courriels.
Le voyage d'avion se passe bien, même si on m'a donné un siège différent de celui qui était prévu (j'ai perdu le hublot, snif!). Je passe les cinq heures entre deux personnes gentilles mais tranquilles, ce qui me permet de travailler sur le cours que je donne demain et après-demain.
Période courte de transfert à Vancouver. Mon avion a environ une quarantaine de minutes de retard, mais j'ai beaucoup de travail et ça ne me pose pas de problème. Il y a une menace d'alerte d'incendie, dont on nous fait part dans ma section de l'aéroport, alors je range mon ordinateur une quinzaine de minutes plus tôt que souhaité au cas où on nous demanderait de sortir rapidement. Finalement, rien de grave ne se produit, et nous finissons par embarquer.
Le vol de Vancouver vers Seattle, déjà court (45 minutes environ), ne me permet pas de travailler car il est... turbulent. Il n'y a pas non plus de service de verre d'eau pour cette raison.
Une fois à Seattle, je me paie la navette (un tiers du prix du taxi), qui m'amène à l'hôtel où je suis bien reçu. Je fais un aller / retour épicerie rapidement (à pied, c'est pas très loin, une dizaine de minutes... mais il pleut beaucoup) pour me prendre quelques fruits, légumes, un peu de fromage, des grignotines, de la bière locale et un sandwich pour mon souper de fin de soirée. Je travaille en vue du cours de demain jusqu'à ce que mon corps me dise que c'est assez...
Je donne aujourd'hui et demain un cours nommé Thinking Small, destiné à des gens intéressés par le contrôle sur la taille des programmes et des objets qu'ils contiennent. J'ai donné un cours ici en 2016, devant un très grand groupe et sur un sujet fortement spécialisé, et un cours en 2017, devant un tout petit (mais fort sympathique) groupe sur un sujet plus généraliste.
Cette année, je suis revenu vers un sujet plus spécialisé et j'ai une classe de taille moyenne, incluant un petit nombre de bénévoles. Ce sont des gens intéressants et pertinents, et j'aime beaucoup travailler avec elles / eux. J'ai donné (je pense) un bon cours, mais je crains de manquer de temps pour préparer le nécessaire en vue du cours de demain après-midi.
J'ai pu discuter de bases sur la mesure du temps d'exécution des fonctions, (certains m'ont dit qu'ils ont trouvé cette partie facile, mais faut bien placer ses idées), de bases sur la gestion de la cache, et de bases sur la taille en mémoire (en particulier, l'opérateur sizeof) et sur l'alignement des données (incluant les opérateurs alignas et alignof), de même que sur l'interrelation entre ces deux idées.
Ceci semble simple, mais avec exercices, exploration des côtés obscurs de ces idées, et applications concrètes de ces idées dans la programmation, mesures à l'appui, ce fut un solide sept heures et il fallait y aller doucement. C'était difficile pour plusieurs.
Le goûter du matin est composé de bagels avec différentes garnitures. Je me permets du fromage à la crème au saumon, câpres, tomates, concombres et oignon rouge. C'est très bon. Étant à Seattle, le café est fourni par Starbucks, mais c'est compréhensible et, pour eux, c'est une entreprise locale.
J'ai croisé Nicolai Josuttis et Rainer Grimm, qui enseignaient tous deux dans les salles adjacentes. Ce fut agréable de bavarder avec Rainer Grimm; nous avions eu des échanges épistolaires par le passé. Nicolai Josuttis était occupé (il est très connu ici) mais semblait d'excellente humeur et nous étions tous deux contents de nous revoir.
Le repas du midi était bon, mais on tend à bien manger au Meydenbauer lors des prestations de cours : de bonnes salades, une vinaigrette au champagne, du boeuf braisé, quelque chose qui évoque le quinoa, un dessert que mon amoureuse aurait bien aimé (sorte de croustade aux fraises dans un petit pot), etc. Nous sommes très nombreux cette fin de semaine et on nous a avertis que la salle à manger ne pouvait accueillir toutes les participantes et tous les participants, mais on s'éparpille et tout va bien.
Le goûter de fin d'après-midi était fait de tranches de saucisses avec choucroutes assorties et de petits pains pour se faire un mini burger. Ça fait de petites bouchées; simple mais agréable.
En soirée, j'ai bavardé un peu avec mes enfants les plus jeunes, Ludo et Vayda, de même qu'avec mon amoureuse Za. Ils semblent avoir passé une charmante journée. Vayda grandit, c'est une jeune ado maintenant, et Ludo est allé aider les pompiers à arroser une cible avec un boyau d'arrosage.
Je me suis levé tôté Je vise 4 h 45 heure locale quand je suis ici, ce qui me permet de travailler sur mon matériel avant le début de la journée et ce qui réduit l'impact du décalage horaire. J'ai du matériel en quantité, et je suspecte que j'en aurai trop pour la journée (une bonne chose), mais il n'est pas entièrement exprimé sous forme de diapositives électroniques. Exprimé autrement, je ne suis pas prêt, mais le cours va être intéressant et je vais compléter le matériel officiel plus tard cette semaine.
Aujourd'hui, je suis entré dans les subtilités du placement new et sur ses applications dans la gestion interne efficace de l'espace occupé par les objets. Rapidement, j'ai constaté que je devrais expliquer new tout court pour que le reste fasse du sens à leurs yeux; même parmi les expertes et les experts, c'est pas le genre de truc que tout le monde connaît. Ces mécaniques interagissent avec les considérations d'espace et d'alignement discutées la veille.
Une fois les subtilités de ces mécaniques explorées, je me suis lancé dans les arénas, puis dans les allocateurs, pour montrer les vieux allocateurs et les nouveaux (depuis C++ 11). J'ai écrit un allocateur utilisant un tampon sur la pile d'exécution, et nous avons mesuré les gains (appréciables) associés à cette pratique de même que les subtilités des techniques associées.
En après-midi, j'ai exploré diverses tactiques pour réduire la taille des objets en mémoire, incluant des designs comparatifs pour diverses classes « classiques » (avantages et inconvénients). J'ai aussi exploré les aléas de certaines optimisations d'espace et de disposition des données, qui compliquent l'écriture correcte de l'opérateur d'affectation et qui empêchent la rédaction d'un mouvement efficace. J'ai fini par une discussion d'une implémentation naïve mais fonctionnelle d'une chaîne de caractères SSO (attention, le lien contient du code qui n'est pas à jour; je l'ai réécrit ce matin mais la version à jour n'est pas encore en ligne!), une vraie discussion où nous avons échangé collectivement sur des améliorations possibles du design naïf, de même que d'une esquisse d'une implémentation SOO de std::function. J'ai survolé vector<bool> et bitset<N> au passage, mais le temps nous a manqué.
J'ai croisé plusieurs personnes au cours des pauses. Un truc amusant : le trio fait de Scott Meyers, Kate Gregory et Andrei Alexandrescu tenait une formation d'un jour sur l'art de donner des formations (ils sont tous trois excellents!), mais ont choisi de procéder par la pratique : les participantes et les participants devaient donner un mini cours de cinq minutes devant le groupe... et se faire critiquer (constructivement) par le trio. J'ai eu un retour de la part d'Adi Shavit et de la part de Victor Curia : les deux ont trouvé l'expérience intéressante... mais ont avoué avoir trouvé intimidant de présenter devant des gens d'une telle stature.
J'ai eu des offres pour aller souper à l'extérieur, mais je me suis excusé de ces occasions, souhaitant me reposer un peu (les gens ont compris; on se reverra plus tard). Je suis repassé par ma chambre pour me rafraîchir, changer de vêtements (ce sont de longues journées!), me raser, puis je suis allé à la réception.
C'était une réception chouette. Nous sommes presque 1250 cette semaine, en plus de certaines personnes qui sont venues pour les formations (dont la mienne) mais ne restent pas pour l'événement entier (typiquement parce que leur employeur. La réception se tenait non pas à l'étage (nous sommes trop nombreuses et trop nombreux), mais bien dans l'immense salle où se tiennent les Keynotes qui accueillent tout le monde une fois par jour. Une bonne idée : nous avons encore cette année des Poster Sessions, où des gens viennent présenter des idées ou des projets intéressants (j'étais sur le comité qui les a sélectionnés; on en a une quinzaine cette année!), et ces affiches sont dans la salle où nous bavardons et prenons un verre.
C'est une réception chouette, où je reste un peu moins de deux heures et qui me permet de renouer avec plusieurs personnes, de même que de rencontrer des tas de gens à qui je n'ai parlé que par écrit auparavant. En particulier, j'ai pu échanger un peu avec mon sympathique ami et collègue Billy Baker, un plaisir chaque fois renouvelé. J'ai pris un peu de temps avec Bob Steagall, que j'avais un peu accompagné dans sa préparation et qui donnait un cours comme moi en fin de semaine... mais pour lui, c'était une première, alors nous avons un peu échangé sur son expérience.
J'ai eu la chance d'échanger un peu avec Rob Irving et Jason Turner (un ami), qui tiennent l'excellent balado CppCast où je suis passé en entrevue à quelques reprises déjà (ici, ici, ici), ce qui m'a permis de leur dire (et c'est vrai!) que plusieurs m'ont dit avoir choisi de suivre mon cours (ou ont fait le détour pour me dire que j'étais leur deuxième choix, ce qui est charmant!) après avoir entendu mes entrevues. Je pense qu'ils étaient contents de le savoir.
J'ai eu un peu de temps pour parler avec Adi
Shavit, très sympathique, et j'ai échangé brièvement avec plein de gens
avec qui j'aurais aimé parler plus longtemps (Zoetica Ebb,
Aaron Ballman, Ólafur Waage, Mathieu Ropert,
Simon Brand,
plusieurs autres... Désolé si je ne vous ai pas nommé!). J'aurais voulu parler
avec Patti Galardo, fort sympathique à l'écrit mais qui
semblait visiblement ravie d'être là et se trouvait au coeur de plusieurs
conversations, alors je me reprendrai dans ce cas .
J'ai évidemment pu saluer plusieurs amis et collègues récurrents avec lesquels
j'ai le plaisir de travailler depuis cinq ans lors de ces événements ou lors de
rencontres du WG21 (Chandler Carruth,
Jens Weller, Hubert Tong,
JF Bastien, Richard Hodges, etc.).
Mention particulière à Hana Dusíková, une des artisanes de l'antiviral Avast. Elle donnera sa première présentation formelle cette année, mais son Lightning Talk de 2017 sur les expressions régulières résolues à la compilation a fait beaucoup jaser. Elle m'a informé qu'il se peut que la rencontre du WG21 au printemps 2020 se tienne à Prague, une ville que je veux visiter depuis très longtemps. Je vais essayer d'amener Za avec moi pour celle-là. Autre mention particulière à Andrew Pardoe, qui ne sera pas là toute la semaine mais qui est venu saluer des gens... et faire du recrutement. Il est passé du monde de C++ (il siègeait au WG21) à celui de l'optimisation des compilateurs, et de Microsoft à Facebook. Toujours sympathique, celui-là.
Durant ces réceptions, il y a toujours des bouchées très agréables, mais je n'ai pas pu manger grand-chose car les conversations abondaient. Je peux vous dire que ce que j'ai pu goûter (un micro empanada à la saucisse, un autre aux artichauts, un mini Crab Cake) était délicieux.
Au retour à l'hôtel, j'ai croisé Alan Talbot qui était d'excellente humeur. J'ai pu le remercier pour un petit truc qu'il a fait passer pour C++ 17 (faire en sorte que la méthode emplace_back() des conteneurs retourne une référence sur l'objet construit) me rendait service au quotidien (je me suis aperçu que ça pouvait simplifier plusieurs manoeuvres dans le code qui sous-tend ma thèse de doctorat).
Il m'a confié que c'était pour lui une question de corriger une gaffe du passé : il avait contribué à l'introduction de la fonction emplace_back() pour C++ 11 et c'est à l'usage qu'il s'était aperçu que la forme suivante :
v.emplace_back(args...);
f(v.back());
... apparaissait souvent en pratique, et pourrait se simplifier à :
f(v.emplace_back(args...));
... avec le changement en question. C'est dans des petits détails comme ceux-ci que C++ 17 montre ses petits côtés plaisants dans la programmation au quotidien : pas conceptuellement majeur du tout, mais une meilleure interface et une programmation plus agréable. Le langage a pris beaucoup de maturité, selon moi,
J'étais très fatigué en fin de soirée, alors je n'ai pas travaillé très longtemps avant de sombrer dans le sommeil.
Levé à 4 h 45 comme à l'habitude. Après la douche, je me suis fait un café et j'ai écrit un résumé de ce qui s'est passé au cours des deux dernières jours (ci-dessus).
Ce matin, le feu roulant de l'événement débute. En plus des présentations auxquelles je planifie aller (mon plan de match est ci-dessous; j'ajusterai en fonction de ce qui se passera), j'ai :
Sur le chemin vers la conférence, je croise plusieurs collègues du comité. L'ambiance semble excellente et les sourires sont nombreux. Il y a déjà beaucoup de gens sur place à mon arrivée vers 8 h 20 alors que la présentation de Bjarne Stroustrup est prévue pour 9 h.
Une belle surprise : Antoine Desbois, un de mes anciens (et brillants) étudiants à l'Université de Sherbrooke, et présent ici avec un de ses collègues. Je suis toujours content de les revoir, et de savoir qu'ils continuent à progresser une fois sur le marché du travail.
Les affiches du Poster Session ont été placées sur la route menant vers l'offre de nourriture pour celles et ceux qui souhaitent une bouchée le midi sans quitter les lieux (car il y a des panels sur l'heure du dîner aussi), ce qui amène les gens à passer devant. C'est une excellente idée : nous souhaitons que les gens les examinent, posent des questions aux présentatrices comme aux présentateurs, et en viennent à voter pour leurs préférés.
Ce matin, mon puzzle du SCM Challenge sera présenté au public qui pourra essayer de le résoudre pour les prochaines 36 heures. J'espère que les gens s'amuseront!
Nous sommes rendus si nombreux qu'il a fallu installer quatre écrans géants dans la salle. Le groupe rock qui assure l'animation en périphérie de la plénière se permet des choristes maintenant. Fidèle à mes habitudes, je me trouve un endroit non-loin d'une prise de courant près d'un mur, pour faciliter la prise de notes.
J'ai pris quelques secondes pour saluer Walter E. Brown, que j'aime beaucoup et qui m'avait demandé un service cet été que je ne suis par parvenu à lui rendre, car je souhaitais lui présenter mes excuses. Il a été gracieux, comme toujours.
Jon Kalb présente une vidéo promotionnelle pour ouvrir le bal. Bien fait! Il accueile les gens en les remerciant pour leur présence ici cette semaine. Comme c'est toujours le cas lors des plénières, nous avons droit aux nouvelles du jour : fonctionnement du Wi-Fi, canaux de communication officiels, Lightning Talks (micro présentations) et Open Content (présentations impromptues), la compétition d'affiches, le puzzle (avec mon nom sur grand écran...), les événements périphériques (dont le souper pour étudiant(e)s de ce soir), la librairie, les exhibits commerciaux, la rencontre du SG14, le code de conduite (pour lequel Chandler Carruth et Kate Gregory sont les figures publiques officielles), les sponsors (je remarque que plusieurs User Groups en font partie; peut-être le C++ Users Group de Montréal l'an prochain?), les sondages...
Jon Kalb présente ensuite Bjarne Stroustrup (qui n'est pas exactement un inconnu).
Pour la vidéo, voir https://www.youtube.com/watch?time_continue=2&v=HddFGPTAmtU
Pour les diapositives, voir ceci
Bjarne Stroustrup prend la parole.
Le projet de cette présentation est de présenter les concepts, qui s'annoncent pour C++ 20. Ce qu'ils apportent à la programmation générique, ce qu'ils sont, comment définir de bons concepts.
Il retrace l'origine des concepts aux travaux de Dave Musser et Alex Stepanov, et relate son objectif de rendre la programmation générique normale et accessible.
L'objectif général est simple : écrire du meilleur code. Il dit ne pas vouloir discuter de détails techniques, laissant ces sujets à d'autres.
Le Concepts TS a été accepté en 2016, et a cheminé (trop lentement à son avis) à travers le processus de standardisation. Ceci inclut des formes courtes, les clauses requires, les expressions requires, et les concepts requis pour implémenter les intervalles dans la bibliothèque standard.
Il mentionne aussi ce qui demeure en développement, et me semble être plutôt politiquement correct considérant l'importance de certains de ces éléments à ses yeux.
Pour que la programmation générique soit « juste de la programmation », il faut améliorer la syntaxe et la validation des types. Les modules aideront selon lui à une meilleure organisation du code, mais il ne compte pas parler de cette partie de C++ 20 ici.
Mieux spécifier les interfaces est l'un de ses principaux objectifs; les macros sont du poison, nous devons faire mieux. Évidemment, le principe selon lequel les abstractions de C++ doivent être à coût nul, qui remonte à au moins 1987, demeure. L'avantage premier est concepts est de permettre une meilleure spécification d'interfaces. Ceci est particulièrement important dans le développement de logiciel à grande échelle.
Bjarne Stroustrup revient dans le passé et réexamine les interfaces originales de C, dangereuses et inacceptables selon lui. Il relate sa contribution à l'introduction des protoypes de fonctions à titre de mécanisme obligatoire, en 1979, pour éviter que tout soit un int par défaut. Il trace un parallèle avec les templates en 1988, qui permettent une programmation générique sans contraintes. Quelques exemples d'appels à sort() générant de très mauvais messages d'erreurs sont présentés.
Évidemment, les templates demeurent un immense succès. Ils sont flexibles, Turing-Complete, hyper efficaces... mais ont des tas de défauts, surtout sur le plan de la charge syntaxique, et tendent à ralentir la compilation.
L'exemple de sort(Sortable&) est présenté. C'est le classique exemple de concept. Un exemple d'implémentation correcte délègue à std::sort() sous la couverture et profite du inlining. Il en profite pour montrer que les intervalles simplifient les usage communs des algorithmes standards, et il montre comment les CTAD allègent l'écriture.
S'ensuit une discussion sur la relation entre types et concepts. Le type décrit entre autres la structure d'un objet en mémoire, et se rapporte à l'implémentation. Un concept exprime principalement ce qu'un objet est en mesure de faire, et se rapporte à l'interface.
Un exemple charmant est template<class T> concept Int = Same<T,int>, par lequel il utiliser des types génériques comme des primitifs.
Bjarne Stroustrup discute de la syntaxe concise et de la confusion sur sort(Sortable&&) (référence de relais ou référence sur un rvalue?). Il dit qu'il voit bien la résistance du comité, et pense pouvoir vivre avec sort(Sortable auto&&) pour lever l'ambiguïté.
Les concepts contraignent la généricité et réduisent la dépendance envers auto. La surcharge de fonctions devient aussi nettement plus agréable.
Bjarne Stroustrup montre comment la spécialisation et l'optimisation d'une fonction comme advance() peut être simplifiée par voie de concepts. Ceci montre que le recours aux traits sera probablement moins répandu (ce qui simplifiera la programmation), en particulier enable_if. Il faut aussi remarquer que les temps de compilation seront meilleurs.
Bjarne Stroustrup montre les propriétés conditionnelles : un pointeur intelligent qui n'expose des services que si un certain concept est rencontré (remplacement direct d'enable_if). Un comparatif concept / enable_if met en relief la simplification significative du code.
Le recours à des concepts pour contraindre les valurs de retour des fonctions est ensuite mis de l'avant. C'est ça ou beaucoup de commentaires, parfois (note personnelle : quand on écrit de petites fonctions, c'est beaucoup moins problématique, mais bon...)
Bjarne Stroustrup revient sur la lourdeur de la syntaxe des templates, qui était délibérée à l'époque (le mécanisme était si novateur qu'il faisait peur), ce qu'il accompagne d'une discussion sur l'importance d'une syntaxe naturelle. Il discute de l'importance de comprendre une fonction sur la base de sa signature. Les intervalles reviennent encore de l'avant.
Bjarne Stroustrup suggère de ne pas trop se baser sur les vieilles bibliothèques, adaptées pour profiter des concepts, pour approcher la question de la lisibilité du code reposant sur des concepts, et de réfléchir sur la base du nouveau code. Il mentionne que auto est le concept le plus général, mais peut s'exprimer sous forme de concept comme template <class T> concept Auto=true;
Un présentatiom du code avec / sans types s'ensuite, pour discuter des irritants des solutions trop générales. Bjarne Stroustrup dit que les concepts vont changer notre perception de la programmation... mais que ça va prendre des années, le changement étant majeur. Il est temps de s'y mettre selon lui, car 2020 est tout près...
Un historique des concepts depuis 1981 (Alex Stepanov) est présenté. La STL d'origine, en 1994, était spécifiée sous forme de concepts, mais en prose. Alex Stepanov est cité comme disant que les concepts ne parlent que de sémantique, même si les concepts n'ont en fait aucun composant sémantique. Selon Bjarne Stroustrup, les concepts sont des prédicats statiques. Plusieurs concepts existent implicitement dans le langage (arithmétique, entier, flottant, itérateur à accès direct...); ce qui manque est un support langagier formel.
Un bon concept représente un part fondamentale d'un domaine. Ce n'est pas un requis d'implémentation. Un concept Number est meilleur qu'un concept hasPlus : les concepts devraient décrire des groupes cohérents de fonctionnalités; en ceci, les concepts rejoignent les types. Il montre une fonction qui utilise += et mentionne que + et = auraient aussi été corrects dans une implémentation, donc qu'exiger la présence d'un opérateur spécifique serait contreproductif.
Les concepts ne sont pas des métatypes ou des Type Classes. Plusieurs concepts prennent plus d'un type en paramètre. Bjarne Stroustrup présente un type qui utilise des concepts (plutôt qu'une fonction dont la signature utilise des concepts.
La définition de concepts suit, en combinant des concepts plus simples ou à l'aide d'expressions requires. Bjarne Stroustrup fait remarquer que la bonne rédaction de concepts demande de l'expérience et recommande de commencer par ceux dans <concepts> et <ranges> pour commencer. Les concepts moins complets sont utiles pour développement, mais ne devraient pas contribuer aux interfaces de nos fonctions. Selon lui, requires requires est une erreur de design la plupart du temps,
Bjarne Stroustrup discute des correspondances accidentelles (l'exemple de Shape::Draw() et CowBoy::Draw() si le concept est Drawable, que Herb Sutter ramène à l'occasion). Cela peut arriver, mais c'est un signe selon lui que le design est fautif (de ce que je peux voir, Drawable serait une interface au sens du schéma de conception, donc une structure instrusive, pas un concept).
Les concepts ne valident pas les définition des fonctions, donc il restera des messages d'erreurs pénibles à l'occasion. Cette imperfectipn ne devrait pas empêcher l'adoption du mécanisme selon lui. Bjarne Stroustrup dit qu'on sait commenr faire (Gabriel Dos Reis a fait des recherches en ce sens), mais que ce n'est pas ce que nous aurons en 2020, et nous verrons si c'esr la chose à faire ultérieurement. En attendant, nous avons static_assert, et nous avons des « classes archétypes ».
Certains concepts de haut niveau sont pénibles (les contraintes de merge() et d'accumulate(), en particulier), mais c'est un enjeu de syntaxe. Pour ces cas un peu particuliers, des méta concepts sont définis dans une optique simplificatrice. Les concepts sont des fonctions sur les types, et il est sain de les traiter comme telles.
Les concepts facilitent le raisonnement sur le code, et enrichissent la sémantique des spécifications.
Ses suggestions :
Q : les concepts servent-ils à décrire une algèbre?
Bjarne Stroustrup : pas seulement. Ça ne se limite pas aux mathématiques
Q : dire que sort() accepte un Sortable et que merge() accepte des Mergeable me semble un peu circulaire. Peut-on spécialiser des concepts pour sélectionner la version choisie sur la base du caractère plus ou moins contraint d'un concept?
Bjarne Stroustrup : c'est une question complexe, mais oui.
Q : pourquoi un concept comme EqualityComparable<T> vérifie-t-il que == et != soit supporté, mais pas que les valeurs retournées sont l'inverse l'une de l'autre? Les contrats peuvent-ils aider ici?
Bjarne Stroustrup : les contrats s'appliquent aux valeurs, les concepts s'appliquent aux types.
Q : il y a des concepts qui sont partiellement formés pour certains types (LessThan pour des float, par exemple)
Bjarne Stroustrup : une contrainte incomplète demeure préférable à une absence de contraintes. Vérifier les débordements, par exemple, est extrêment difficile (ça revient à essayer de prouver un programme). Bjarne Stroustrup nous rappelle que nous avons tendance à être très imaginatifs pour identifier des problèmes potentiels, et que nous sommes beaucoup moins efficaces pour imaginer les bénéfices.
Q : comment constexpr interagit-il avec requires?
Bjarne Stroustrup : il n'y a pas pour le moment de moyen de faire requires constexpr, mais les concepts devraient faire disparaître beaucoup de cas d'utilisation d'enable_if. Nous avons un rapport d'Eric Niebler indiquant que la bibliothèque d'intervalles compile 25% plus rapidement avec concepts que sans concepts
D'autres questions portent sur les évolutions divergentes de C (généricité par voie de macros) et de C++. Sans surprises, Bjarne Stroustrup est d'avis que C fait fausse route. On demande si les concepts pourront être spécialisés. Bjarne Stroustrup dit que ça dépend du sens qu'on donne à ce mot. Une question porte sur les classes abstraites : seront-elles remplacées par les concepts? Bjarne Stroustrup dit que les concepts n'ont aucun coût à l'exécution, contrairement au polymorphisme classique, mais que les deux ont leur rôle à jouer.
J'ai bavardé avec Hana Dusíková à propos de sa présentation de cette semaine. Elle m'a montré ses diapos... L'effort là-dedans est tout simplement hallucinant
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Bryce Adelstein Lelbach prend le relais.
Bryce Adelstein Lelbach explique qu'il passe le plus clair de son temps chez SG1, et qu'il souhaite explique ces trucs fort complexes qui ont trait au modèle d'exécution du langage. Il fera semblant que memory_order_consume n'existe pas.
Bryce Adelstein Lelbach commente par expliquer la règle du as-if [intro.abstract]/4 pour parler des optimisations possibles qui ne sont pas observables... sauf en passant par du comportement indéfini.
Bryce Adelstein Lelbach présente sommairement la machine abstraite du langage : on écrit un programme pour cette machine abstraite, et le programme se réalise sur le matériel par la suite de par l'action du compilateur et de ses bibliothèques. Le code portable modélise des fils d'exécution s'exécutant sur une machine abstraite
Les objets ont une adresse (modulo [[no_unique_address]] évidemment). [basic.memobj] note 32 indique que l'implémentation peut entreposer plusieurs objets au même endroit si as-if est respecté.
Tout fil d'exécution d'un programme est susceptible d'accéder tout objet / toute fonction dans un programme, même un thread_local si on lui refile l'adresse. Les fils d'exécution peuvent s'exécuter concurremment. Bryce Adelstein Lelbach explique le moment où une variable static et où une variable thread_local sont initialisées.
Un fil d'exécution évalue un appel de fonction : une exprssion est une séquence d'opérations et d'opérandes exprimant à un calcul; une sous-expression fait partie d'une expression plus complexe; une full expression n'est pas une sous-expression et peut inclure des sous-expressions qui n'en font pas lexicalement partie (évaluation de paramètres avec valeurs par défaut, par exemple); une évaluation provoque des effets de bord et ceux-ci peuvent être observables (à moins qu'ils ne soient purs). Évaluer une fonction n'implique pas nécesairement les effets de bords.
Bryce Adelstein Lelbach enchaîne avec une explication sommaire de sequenced-before avec la définition contemporaine; il rappelle qu'on se limite aux calculs ici, pas aux effets de bord. Cette relation est asymétrique et transitive. Les full-expressions sont organisées en séquence.
Bryce Adelstein Lelbach parle des indeterminately-sequenced : on ne connaît pas leur ordre relatif mais ils ne se chevauchement pas.
Enfin, Bryce Adelstein Lelbach indique que unsequenced peut entraîner des chevauchements.
Bryce Adelstein Lelbach présente std::for_loop du Parallelism TS qui se comporte comme std::for_each mais avec des indices plutôt qu'avec des itérateurs.
Bryce Adelstein Lelbach montre l'impact des politiques d'exécution sur le code machine généré. C'est chouette!
Les énoncés (statement) se composent de full-expressions.
Pour les règles quant à l'évaluation des fonctions :
Bryce Adelstein Lelbach discute un peu du côté indeterminately-sequenced de l'évaluation des paramètres. Lui et moi ne sommes pas d'accord ici.
Bryce Adelstein Lelbach discute ensuite de l'évaluation des opérateurs et des opérandes
L'étape suivante est synchronizes-with, où on commence à examiner l'ordonnancement inter-thread. Cette relation est asymétrique. On peut y arriver avec divers mécanismes de synchronisation. Bryce Adelstein Lelbach donne quelques exemples (store avec load, unlock avec les lock futurs).
La relation happens-before (mieux connue) est décrite comme une disjonction et sequenced-before, synchronizes-with et de plusieurs happens-before plus simples. Ceci ne devrait pas être observable à partir d'un programme. Bryce Adelstein Lelbach montre que le code machine peut être créatif en autant que les manoeuvres ne soient pas observables. Il suit ceci d'un exemple reposant sur memory_order_relaxed qui ne nous donne pas cette relation; la situation est observable... parce qu'on a donné dans le comportement indéfini
Bryce Adelstein Lelbach passe à la question du Forward Progress :
Le Forward Progress est une garantie qu'un jour, quelque chose d'observable se produira. Conséquemment, une boucle infinie sans effet de bord comme for(;;); est du comportement indéfini au sens du standard
Les garanties de progression sont :
Le fil principal (main()) en C++ offre une garantie de progrès... implementation-defined, avec encouragement de donnes concurrent forward
Les std::thread font de même
Le Boost Blocking est un mécanisme pour bloquer sur un thread avec garanties plus faibles sans bloquer les threads avec garanties plus fortes. Ça ressemble à de l'héritage de priorités [intro.progress]/14. Cela garantie que vos threads enfants vont progresser, mais pas que vos threads soeurs le feront. Ses exemples reposent pour la plupart sur des thread pools.
Bryce Adelstein Lelbach finit par un sommaire des principales idées de sa présentation.
Q : que veut-on dire par cette discussion sur le Boost Blocking et la progression des fils enfants?
Bryce Adelstein Lelbach décrit une situation concrète (de calculs abstraits). Ce n'est pas une garantie qu'il n'y aura pas d'interblocage si des outils de synchronisation sont utilisés de manière risquée.
Q : pourquoi faire semblant que memory_order_consume n'existe pas?
Bryce Adelstein Lelbach : parce que ça complique beaucoup le modèle et les diapositives. L'idée générale demeure la même sans ce cas un peu lourd
Q : pourquoi l'expression a = a + b est-elle considérée un effet de bord même si a n'est pas volatile?
Bryce Adelstein Lelbach : on écrit, c'est un effet de bord. Lire d'une volatile est un effet de bord!
Q : pourquoi un atomic<bool> cause-t-il du comportement indéfini dans le cas de l'accès memory_order_relaxed?
Bryce Adelstein Lelbach : parce que memory_order_relaxed n'entraîne pas synchronizes-with
Bryce Adelstein Lelbach a fait du bon boulot. Les questions se terminent vers midi cinq.
Je me suis pris un sandwich thaï (bon, mais salissant) et un biscuit pour accompagner mon café. 9 USD, mais un très bon service.
Ce panel implique Michael Caisse, Stephen Dewhurst, Nicolai Josuttis et Scott Meyers
Jon Kalb présente sommairement les membres du panel. Il en profite pour parler de l'importance du rôle des formatrices et des formateurs.
Stephen Dewhurst : j'ai commencé à offrir des formations un peu par accident. C'est mon travail depuis des décennies. J'aime C++, le mode de pensée, mais j'aime aussi le volet social de la programmation, la réflexion, les discussions. J'ai beaucoup aimé la présentation de BS ce matin, et elle va influencer mon enseignement à partir de maintenant.
Nicolai Josuttis : j'ai commencé il y a une trentaine d'années, avec C puis avec C++. Je hais C++ (les gens rient!), c'est un cauchemar pour les débutants. Juste l'initialisation des variables... Je pense que nous devons définir un guide de style commun et nettoyer le langage un peu
Scott Meyers : j'ai commencé à enseigner C++ pour programmeuses et programmeurs C. J'ai constaté que la quantité de détails les submergeait, et j'ai commencé à réfléchir à des règles simples à mémoriser (les règles ont changé entre alors et maintenant), ce qui a donné de bons résultats en élevant un peu le niveau d'abstraction du discours.
Michael Caisse : j'ai donné ma première formation vers 1992. Ce n'était pas vraiment un cours formel; j'étais seulement tanné de voir le code que mes collègues produisaient et je voulais améliorer mon propre sort. J'aime rencontrer des gens qui ont une pensée et des idiomes différents des miens.
Q : nous avons des tas de trucs chouettes avec C++ 17 et C++ 20. Les règles et les saines pratiques évoluent, mais il y a tellement de matériel... Pourtant, les entreprises utilisent encore un mélange de C, de vieux C++. Comment décide-t-on quoi enseigner et quoi ne plus enseigner?
Michael Caisse : en réalité, chaque formation que je donne est fortement personnalisée en fonction des besoins immédiats des gens qui m'engagent. Ça ne me sert pas de montrer du C++ 17 chez des gens qui ne peuvent utiliser un compilateur plus récent que C++ 11. Le C++ moderne est un mode de pensée, pas un numéro de version. Aussi, j'enseigne surtout à des programmeurs expérimentés
Scott Meyers : il faut gérer les transitions efficacement. On faisait ceci avant, on peut désormais l'approcher ainsi. J'y vais avec prefer this to this, et les gens tendent à adopter ces pratiques même quand les anciennes pratiques étaient répandues. Il faut prendre soin d'expliquer pourquoi il serait sage de migrer. Maintenant, C++ est en état de transition continue, et il devient plus facile de dire pour atteindre cet objectif, le chemin le plus simple est ceci.
Nicolai Josuttis : j'essaie encore de comprendre C++ 11 et C++ 17, alors je ne suis pas à C++ 20. Il n'existe plus personne qui comprenne vraiment C++
Stephen Dewhurst : ce qui change aussi est la manière que nous avons de comprendre les programmes et la programmation. Pour moi, remplacer enable_if par des concepts est un changement de mode de pensée. On peut réfléchir à ce qu'on souhaite accomplir, puis au chemin vers l'atteinte de cet objectif. La simplicité est une propriété émergente de la complexité de C++ pour qui applique des idiomes contemporains.
Jon Kalb dit recevoir des propositions de conférences sur des trucs de C++ 23, mais des tas de gens essaient encore de comprendre C++ 11.
Nicolai Josuttis : trop de propositions que nous recevons ne viennent pas avec une justification claire, ou avec une exploration détaillée des conséquences. L'initialisation demeure un cauchemar.
Q : je vois des tas de jeunes programmeuses et de jeunes programmeurs submergés par tout ce qu'il y a à apprendre. Une partie du travail est de désapprendre des idées qui ont été internalisées et qui bloquent la progression de la pensée. Comment vaincre la peur, les croyances irrationnelles?
Scott Meyers : être débordé par les détails se résout en plaçant les gens en situation de réussite. Réduire le bruit des détails. Le succès entraîne la confiance. Pour ce qui est de gérer le changement... c'est difficile pour tous les humains. À mon avis, la meilleure solution est d'avoir un argument technique; ce qui fonctionne avec C++ est la vitesse d'exécution, car cette communauté s'y abreuve qu'elle en ait besoin ou pas. Enfin, il y a le facteur « this is cool » qu'il ne faut pas négliger.
Nicolai Josuttis : et « ceci est moins dangereux »?
Scott Meyers : ... ouais, des fois (on rit)
Jon Kalb parle de l'intérêt d'inviter un expert pour les formations. Ceci permet d'installer une forme d'autorité morale qu'on n'aurait pas avec des collègues.
Michael Caisse : dans mon entreprise, nous sommes souvent appelés à résoudre les problèmes des autres entreprises, et c'est rarement une question de talent; juste avoir un peu de bon sens mais d'une personne de l'extérieur peut tout faire débloquer.
Arthur O'Dwyer : C++ est multiparadigme. Arrive-t-il que vous soyez appelés à donner une formation, mais que ce que vous enseignez en termes de mécanismes ou de pratiques ne soit pas bien reçu par vos hôtes? Y a-t-il des paradigmes que plus personne ne veut apprendre?
Michael Caisse : en 1990, quand j'ai commencé à utiliser C++, nous avions la visite de gros noms de la programmation orientée objet. Il se trouve que certains problèmes se résolvent mieux avec certaines techniques, et nous avons la chance d'avoir un langage qui ouvre la porte à de multiples techniques. Il faut adapter ce qu'on enseigne aux besoins du domaine visé.
Nicolai Josuttis : j'ai une liste de 60 sujets. J'envoie cette liste aux gens qui m'engagent. Je leur demande ce qu'ils veulent, un priorisation, et j'assemble mon matériel en conséquence. Je m'intéresse à la résilience quand j'entraîne des spécialistes de la conduite automobile autonome. Personne n'enseigne C++ en entier
Stephen Dewhurst : aucun domaine n'évolue en éliminant sa culture. Nous devons en prendre soin. En programmation, ne pas savoir comment décomposer en fonction ou gérer des ressources appauvrit la pensée.
Scott Meyers : il y a effectivement des trucs que je n'enseigne plus. Je n'enseigne plus les allocateurs, sauf peut-être pour les gens de systèmes embarqués. J'utilise peu de pointeurs aujourd'hui. Toutes les entreprises estiment que ce qu'elles font est spécial, et qu'il faut adapter le contenu à leur réalité.
Q : comment entraîner quelqu'un qui n'a jamais utilisé une ligne de commande?
Scott Meyers : en avez-vous besoin? Si oui, j'ouvrirais une fenêtre, je commencerais par des trucs simples, et je les amènerais avec moi graduellement.
Michael Caisse : souvenez-vous que nous devions, par le passé, compiler gcc nous-mêmes. Maintenant, nous avons des outils de développement plu sophistiqués. Il arrive que les outils obscurcissent la tâche, qu'on oublie comment fonctionne un éditeur de liens par exemple.
Matteus Pusz : comment expliquer à des gens ce qu'ils ont besoin d'apprendre quand ils sont certains de savoir ce dont ils ont besoin?
Nicolai Josuttis : j'ai mentionné ma liste de sujets plus tôt... En pratique, je finis par enseigner souvent le même chose (rires!)
C'était un bon panel, mais j'ai quitté avant la fin pour mon entrevue avec Channel 9 (Steve Carroll et Nick Uhlenhuth). Il y a eu un mini imbroglio sur l'heure de début et le caméraman était en pause, alors je suis allé saluer Walter E. Brown qui est toujours excellent, et dont je vais manquer une présentation pour la première fois depuis que je viens ici, puis je suis retourné à la salle d'entrevue par la suite.
L'entrevue s'est bien déroulée selon moi. Nous avons bavardé de ma présentation de demain, de la formation que j'ai donné hier et avant-hier, des formations en général (l'offre de formation spécialisée ici est complètement folle), etc. Court, mais efficace.
Je me suis dirigé ensuite vers la présentation d'Alisdair Meredith sur les contrats. Ce sujet va influencer ma vie pour plusieurs années et je m'attends à un couverture très détaillée des enjeux, si je peux me fier aux présentations qu'il nous a données par le passé. J'en ai profité pour féliciter Bryce Adelstein Lelbach pour sa très bonne présentation de ce matin (c'était bien fait, et le sujet était rude d'approche)
Pour la vidéo, voir https://www.youtube.com/watch?v=aAFRxRznVjQ
Pour les diapositives, voir ceci
C'est une très grande salle ici, mais il y a lieu de s'attendre à ce qu'il y a beaucoup de gens dans la salle. On parle d'un sujet chaud et d'un des principaux ajouts au langage avec l'avènement de C++ 20.
La première partie vise à expliquer ce qu'est la programmation avec des contrats. La deuxième doit parler des saines pratiques pour exprimer des contrats.
Alisdair Meredith demande qui est heureux / neutres / tristes ou pas d'utiliser dans son code les types int, unsigned int et double. Les gens semblent heureux pour int (80-15-5), unsigned int (10-45-45), double (40-50-10). Ils poursuit avec char const * (5-20-75), string_view (40-45-5), string (15-30-55). Il reviendra sur le sujet
Alisdair Meredith : un contrat est une entente enforcable by law. Un échange de promesses entre client et fournisseur. Le fournisseur se porte garant du contrat, le client peut rapporter des bogues. Changer un contrat ne peut être fait de manière unilatérale, car c'est un bris de promesse.
Alisdair Meredith : le standard de C++ est un contrat de 1500+ pages. Tu me donnes un programme qui respecte les règles, je te donne quelque chose que la machine abstraite peut digérer (modulo les limites matérielles de la machine réelle). Si tu me donnes un programme qui ne respecte pas les règles syntaxiques, je te donnerai au moins une erreur. Idem pour des erreurs syntaxiques. Je peux quand même te donner un programme, mais tu donnes dans le comportement indéfini alors tu auras peut-être des surprises.
Alisdair Meredith : en Java, c'est semblable à ceci près que si le programme n'est pas syntaxiquement valide, tu n'auras pas de programme utilisable. Si tu fais des bêtises à l'exécution, tu recevras une exception au visage. Java n'a pas de comportement indéfini
Alisdair Meredith : un contrat comprend des précondditions et des postconditions. La précondition est une promesse proférée par le client; la postcondition est une promesse proférée par le fournisseur. Les invariants sont aussi sur les épaules du fournisseur. Si le client appelle une fonction sans en respecter le contrat, le client est responsable pour le comportement indéfini
Alisdair Meredith : si les préconditions sont respectées par le client, le fournisseur s'engage à respecter les postconditions. Une API peut malgré tout échouer faute de ressources. Les échecs doivent être signalés, ce qui peut être complexe dans un système réparti
Alisdair Meredith : les invariants se comportent comme des préconditions et des postconditiosn implicites. Ils doivent tenir même si une fonction se termine par une erreur ou par une exception.
Ce trio (préconditions, postconditions, invariants) permet de raisonner sur la base du code source
Alisdair Meredith : un bon contrat explique clairement comment les erreur seront rapportées.
Alisdair Meredith : les garanties sont basic (lors d'un échec, pas de fuites, pas de bris d'invariants), atomic/transactional (lors d'un échec, aucun état observable n'a changé), no-fail (aucun échec sir les préconditions sont respectées)
Alisdair Meredith : on peut changer un contrat pour ajouter des détails ou raffermir les garanties. Élargir les préconditions peut briser le code client. En retour, réduire les posconditions peut être correct si le comportement observable ne change pas pour les intrants respectueux des préconditions. Faire des changements plus significatifs implique de la gestion de risques, de la validation avec l'aide des clients, des stratégies de mitigation, des périodes de dépréciation, ou encore le maintien parallèle de la vieille interface et de la nouvelle (ce qui complique les tests)
Alisdair Meredith : le truc est de réussir du premier coup, et de se laisser de l'espace pour croître. Pas simple
Alisdair Meredith : wide contract signifie pas de préconditions (ce qui ne veut pas dire jamais d'échec à l'exécution); narrow contract signifie préconditions sur les épaules de l'appelant, et risque de comportement indéfini lors d'un bris de contrant. Les préconditions tendent à se répandre dans le reste du code client
Alisdair Meredith demande, dans le cas où une fonction ne peut gérer que certaines valeurs, si nous préférons wide contract, narrow contract ou it depends (5-30-50 avec des indécis). Il revient sur les questions initiales : int est mostly narrow, unsigned int est mostly wide mais division par zéro, double est wide mais compliqué. De même, char const * est narrow (valid, null-terminated), string_view est plus large (faut gérer la durée de vie du référé), string est wide mais coûteux.
Alisdair Meredith examine les préconditions de sort(b,e,pred). [b,e) doit former un intervalle valide. pred ne doit pas modifier ses paramètres. b et e doivent être comparables (mais ça fait partie du contrat plus large d'être itérateur). L'intervalle doit pouvoir être parcouru plusieurs fois. La comparaison peut être faite pour toute paire d'éléments dans [b,e). Ls éléments de l'intervalle peuvent être permutés.
Alisdair Meredith examine les postconditions de la même fonction : aucun élément n'a été modifié. Les éléments sont triés dans le respect de l'ordre établi par pred. Le résultat est une permutation de l'intervalle d'origine.
Alisdair Meredith : que se passe-t-il si une exception est levée en cours de tri? Le tri est-il stable? Quelle est la complexité de l'algorithme? Devons-nous allouer des ressources? Pouvons-nous faire le travail avec plusieurs fils d'exécution (ce qui peut mettre de la pression sur pred)?
Alisdair Meredith demande si le contrat de auto sum(int,int,int)->int; est narrow ou wide. Selon lui, on parle de mal documenté, narrow et sujet à comportement indéfini (emvisagez sum(INT_MAX,2,-3)). Une implémentation pas trop mal demande plus de vingt lignes de code. Si on ajoute la contrainte que la somme des valeurs doit être représentable sur un int, le même appel devient un bris de contrat.
Alisdair Meredith discute du développement d'une API pour un type représentant une séquence d'entiers. Deux grandes options de représentation sont first/last et first/length. Il passe ensuite rapidement sur plusieurs diapos car le temps file...
Alisdair Meredith : les garanties d'un contrat s'expriment en langage naturel, et visent à être complets, précis et non-ambigus... mais pas plus que nécessaire
On poursuit dans quinze minutes... Je m'endors : c'est sombre dans les grandes salles pendant les présentations, et je manque de sommeil...
Pour la vidéo, voir https://www.youtube.com/watch?v=7RWJQLpmrS0
Pour les diapositives, voir ceci
J'ai pris une marche du sous-sol au quatrième pour me réveiller un peu, et j'en ai profité pour me faire un thé chai (j'ai atteint mon point de saturation pour ce qui est du café), puis je suis redescendu juste à temps pour la partie suivante.
Alisdair Meredith explique que nous entrerons maintenant plus spécifiquement dans la représentation C++ des contrats. Il répète d'entrée de jeu sa définition généraliste des contrats, et ajoute qu'un contrat devrait être stable suivant sa publication (les amendements doivent respecter les règles énoncées plus tôt).
Alisdair Meredith demande quelle part d'un contrat est implicite sur la base de sa signature. Il prend pour exemple void swap(int&,int&) : le nom, le nombre de paramètres, les références mènent sur des objets valides, la fonction peut modifier les référés, elle ne retourne rien, elle peut lever une exception. Il faut encore documenter la sémantique et le fait que la fonction permute les valeurs des référés
Alisdair Meredith : pas besoin de tout documenter; ce qui n'est pas documenté ouvre la voie pour des évolutions futures. En retour, les clients vont faire des suppositions sur la base de leur compréhension de ces « zones grises ».
En C++ 98, les concepts ayant trait aux garanties incluent const, pass-by-ref (référés implictement valides), types maison (porteurs de leurs propres contrats validés par le compilateur), destructeurs (ce sur quoi repose RAII), les constructeurs (une clé de l'encapsulation : un objet construit devrait respecter et garantir ses invariants; les constructions partielles ne sont pas une idée géniale dans un langage comme C++), les classes abstraites et les méthodes virtuelles (respect des signatures, types de retour covariants) dans l'interface, et les assertions dynamiques dans l'implémentation. Alisdair Meredith insiste sur l'importance de RAII dans le modèle conceptuel du langage.
En C++ 11, on ajoute dans l'interface : override, final, le mouvement (une convention construite sur la base des références sur des rvalue, qui interagit de drôles de manières avec le respect des invariants), noexcept, constexpr et SFINAE (qui existait avant, mais qui a vraiment été généralisé à ce moment, surtout si on le cpmbine avec <type_traits> en général et enable_if en particulier). Dans l'implémentation, on ajoute bien sûr static_assert.
Avec C++ 20, on ajoute à tout cela les concepts sur le plan de l'interface, et les annotations contractuelles sur le plan de l'implémentation. Les concepts parlent des types, les contrats parlent des valeurs. Alisdair Meredith présente des exemples de trucs compliqués à écrire en C++ 17 mais simples à écrire en C++ 20, par exemple le contrat sémantique d'un type comme std::pair à partir de concepts et de clauses requires. Les annotations contractuelles sont [[expects]] pour les préconditions, [[ensures]] pour les postconditions et [[assert]] pour les détails d'implémentation.
Alisdair Meredith discute ensuite de ce qui se passe quand on contrat n'est pas respecté : std::abort(), du moins par défaut (on peut utiliser notre propre fonction). Les exceptions y sont permises, mais la fonction appelée est supposée [[noreturn]]. L'un des objectifs visés est de faciliter les audits de code. Ceci vient avec des Build Modes particuliers qui déactivent ces tests ou pas (Disabled, Default, Audit – ce dernier sera plus coûteux). Les tests peuvent être de granularité default, audit et axiom (ce dernier est simplement tenu pour acquis). Évidemment, le tout doit être bien formé, et les expects sont présumés noexcept. Certaines postconditions peuvent mener à du comportement indéfini mais j'ai manqué la raison.
Q : on peut tricher const avec mutable. Est-ce un bris de contrat?
Alisdair Meredith : ce type de manoeuvre est implicitement correcte dans le langage, et ça joue dans les considérations de Thread-Safety.
Q : j'aime beaucoup [[expects]]. Pour [[ensures]], on me semble donner plus dans les tests unitaires.
Alisdair Meredith : (j'ai manqué sa réponse car je parlais à Jason Turner; je vais rester pour le début de sa présentation)
Q : peut-on utiliser les contrats pour accroîtrs les optimisations?
Alisdair Meredith : dans une certaine mesure, mais il faut se souvenir que les contrats viennent avec un violation handler...
J'ai profité de la pause pour parler à Za, Ludo (sur le point de perdre une deuxième dent) et Vayda (qui étudiait pour un examen de mathématiques), puis je suis allé échanger avec le toujours sympathique Aaron Ballman sur différents sujets... ce qui m'a fait arriver trop tard pour profiter du goûter de fin d'après-midi.
Pour la vidéo, voir https://www.youtube.com/watch?v=uQyT-5iWUow
Pour les diapositives, voir ceci
Jason Turner commence à la minute près, aux applaudissements de la foule.
Jason Turner : Andrei Alexandrescu est dans la pièce voisine et il faudrait faire assez de bruit pour le déranger (rires!)
Jason Turner se présente, mais son rôle dans C++ Weekly et CppCast fait qu'il est plutôt connu ici. Il en profite pour présenter son cours post-conférence et d'autres formations qu'il offira dans les prochains mois.
Jason Turner : le cycle de vie (constructeur -> vie -> destructeur) est un concept clé du raisonnement sur le code en C++, mais il y a parfois des surprises...
Qu'est-ce qu'un objet? En quoi int n; est-il différent de struct S { int n; };? Il n'a pas le même nom (il fait un reinterpret_cast de &s.n en int* pour S s;)
Jason Turner donne la définition de basic[.types]/8, le début de la vie dans [basic.life] et la fin de sa vie (même section). Il fait ensuite des traces de style Noisy (je fais le même genre de truc dans mes cours). Il bascule de ses diapos vers le Compiler Explorer, ce qui est chouette
Jason Turner montre ensuite que les références ne sont pas des objets, et démontre que retourner une référence sur une locale (même const) est du comportement indéfini
Jason Turner remplace le retour d'une const& par un reference_wrapper, mais ça reste indéfini. Les avertissements à la compilation sont différents, toutefois (avec clang, retourner un reference_wrapper ne donne même pas d'avertissement; g++ se plaint d'une variable non-initialisée même si c'est faux, ce qui sent le comportement indéfini à plein nez)
Jason Turner examine le cas des littéraux comme "J'aime mon prof", puis retourner un string_view sur un tel littéral (Ok), puis mettre le littéral dans une temporaire string mais retourne un string_view (comportement indéfini, essentiellement une référence sur une temporaire... mais aucun avertissement). Truc plus amusant :
string_view f() {
const char s[] = "Yo";
return s;
}
... donne dans le comportement indéfini, pas d'avertissement.
Jason Turner aborde ensuite la vie des conteneurs. Il insère un Noisy temporaire par push_back() et les gens sont confus entre mouvement et copie. Il y va avec emplace_back() et on constate que les gens sont moins confortables avec emplace_back() qu'avec push_back(). Truc charmant : emplace_back() sans paramètres appelle le constructeur par défaut
Jason Turner passe aux temporaires (un panier de crabes). Il prend une ref-vers-const sur une temporaire (légal, mais les gens sont confus) provoquant une extension de durée de vie. Amusant ensuite :
struct S { const int &n; };
int main() {
const S &s = S{ 1 };
return s.n; // 1 :)
}
Jason Turner utilise un vector<string> avec de petites chaînes (vector v{"a"s, "b"s }, une seule allocation et c'est pour v). Peu de gens réalisent à quel point SSO est efficace. Avec des accolades et des chaînes longues, la surprise va dans l'autre sens car les initializer_list<T> ne peuvent être copiées (vector v{"LONG"s,"LONG"s} où chaque LONG remplace quelque chose de vraiment long : cinq allocations, soit v, les longues chaînes et leurs copies). Évidemment, si on enlève les 's' des littéraux, ce sont des const char*. Il y a une subtilité quand un utilise array<string,2> a{"LONG","LONG"} qui fait qu'on a exactement deux allocations : array n'a aucun constructeur, pour fins d'efficacité
Jason Turner passe aux nouvelles répétitives for pour montrer l'extension de vie qui fonctionne à un niveau, pas à deux, et présente le nouveau for-init de C++ 20.
Jason Turner couvre quelques cas de if-init / for-init / switch-init, mais je dois quitter...
Je manque la fin car j'ai dit à Zoetica Ebb que j'irais participer à une prise de photos; je ne suis pas très photogénique, alors j'espère que Za va apprécier quand même.
C'est ensuite le moment d'aller au souper avec les étudiantes et les étudiants. Michał Dominiak organise le tout et nous sollicite aussi pour jeter un coup d'oeil aux curriculum vitae demain midi, mais je ne sais pas si je vais participer car le marché du travail est un truc empreint de culture et d'usages et je ne suis pas un « local ».
Je suis allé manger une ou deux pointes de pizza, donc, et bavarder avec des tas de gens sympathiques (dont je ne connais malheureusement pas les noms). Je pense que l'événement leur plait. Ensuite, je me suis installé pour le panel et j'ai bavardé avec Kévin Boissonneault et son collègue, de même que Jens Weller (et plus sommairement avec Arthur O'Dwyer, tout près lui aussi) en attendant le début des discussions.
J'ai enfin au le plaisir de rencontrer Shafik Yaghmour, après avoir échangé avec lui à de multiples reprises.
Ce panel implique Jon Kalb, Marshall Clow, Olivier Giroux, Howard Hinnant, Bjarne Stroustrup, Herb Sutter, Titus Winters et Ville Voutilainen
Jon Kalb demande aux gens de se présenter
Titus Winters : je dirige LEWG et je souhait réduire la quantité d'erreurs de design que nous faisons et que nous devons réparer par la suite. Je m'intéresse à la qualité du design des API et à notre capacité de réparer les erreurs du passé. Je suis content d'être ici et de pouvoir vous entendre.
Herb Sutter : je suis le Chair actuel du comité. Personnellement, j'ai mes objectifs à propos d'une évolution du langage pour simplifier l'acte de programmer avec C++. J'aime aussi l'idée de corriger nos erreurs... À long terme.
Olivier Giroux : je dirige SG1, probablement le plus gros groupe hormis EWG. Les entreprises nous font beaucoup de pression pour progresser. SG1 n'est pas une équipe (c'est un groupe de chats!) mais j'essaie d'en arriver à un travail d'équipe, et à un design plus consciencieux.
Bjarne Stroustrup : mon seul rôle formel est de siéger sur le comité de direction, que je dirige pour le moment dû à un logiciel générant des rôles de manière pseudoaléatoire qui semble avoir un bogue. Nous essayons de donner une direction aux travaux, une fondation solide à notre progression, et j'espère que nous en arriverons à une simplification de la programmation en C++.
Marshall Clow : je dirige LWG et nous sommes un petit groupe responsable pour les deux tiers du texte du standard. Nous cherchons à progresser tout en demeurant conservateurs dans nos changements pour ne pas tout casser. Il nous arrive de briser du code, surtout quand il est très mauvais. On pourrait être plus agressifs.
Howard Hinnant : j'ai quelques rôles dans le comité, dont représenter mon employeur, siéger sur le comité de direction, et choisir le directeur du comité de direction... qui ne sera jamais moi.
Ville Voutilainen : je dirige EWG et je fais en sorte de garder la garderie en ordre. J'essaie de pousser le groupe à terminer les concepts, les contrats, et à tordre le bras des gens qui travaillent sur les modules pour qu'ils finissent leur travail.
Isabella Muerte : pourquoi ne pouvons nous pas nommer unité de traduction... un fichier?
Ville Voutilainen : nous pourrons, mais en quoi cela serait-il avantageux?
Howard Hinnant : il nous faut une proposition
Bjarne Stroustrup : faudrait voir ce qui serait dans ces fichiers
Q: j'aime unique_ptr. J'aime variant. C'est juste déplaisant à écrire avec std::
Titus Winters : si j'avais un pouvoir absolu, on réclamerait l'espace nommé global, mais ce serait une énorme cassure. Nous avons la réputation d'être le langage qui se trompe sur les valeurs par défaut, mais nous vous permettons d'écrire le code le plus rapide...
Herb Sutter : est-ce que j'entends que vous souhaiteriez que new retourne un std::unique_ptr par défaut? (plusieurs mains se lèvent).
Marshall Clow : nous en avons un qui fait cela. Ça s'écrit m-a-k-e-_-u-n-i-q-u-e (rires!)
Bjarne Stroustrup : faut pas oublier que nous avons quelques millions de programmeurs dans le monde, que nous ne pouvons pas rejoindre. C'est difficile de simplifier les choses... Je suis content de CTAD, des intervalles, de ces simplifications de l'écriture... mais plusieurs sont d'avis que nous allons trop rapidement et ne veulent pas voir leur code brisé
Q : dans toutes les compagnies, nous réécrivons la réflexivité. Où en est-on du côté de la standardisation?
Ville Voutilainen : la TS sur le sujet, une fois implémentée, nous donnera une bonne fondation. Ce sera mon prochain projet de pression après les modules, les contrats et les coroutines, en vue de C++ 23. Je compte tordre quelques pouces.
Isabella Muerte : Arthur O'Dwyer travaille sur Trivially Relocatable ces jours-ci. À quel point ceci pourrait-il devenir le destructive move que plusieurs veulent?
Howard Hinnant : ça ne remplacerait pas le mouvement, mais ce serait un bon complément, particulièrement pour la réallocation du tampon des vecteurs
Arthur O'Dwyer : je vais avoir une proposition pour San Diego
Herb Sutter : ça avance, mais les travaux commencent à peine. On pourrait faire plusieurs trucs amusants avec ça, comme une aréna avec compaction
Ville Voutilainen : ce n'est pas la première fois que nous essayons de mettre ceci au point. L'interaction avec la durée de vie des objets est complexe. J'aimerais beaucoup une proposition qui fonctionne
Bjarne Stroustrup : la majorité des efforts requis se trouve dans l'intégration avec les autres mécanismes. L'urgence actuelle est C++ 20
Q : je suis intimidé (rires!) Dans mon entreprise, on utilise peu le mouvement car il faut écrire std::move(). Peut-on rendre les compilateurs plus intelligents pour automatiser le choix de déplacer? Le risque de use-after-move est un stress...
Herb Sutter : plusieurs analyseurs statiques commencent à détecter ces bogues. On commence aussi à trouver des std::move() inutiles
Bjarne Stroustrup : en pratique, le mouvement implicite est souvent suffisant
Ville Voutilainen : sur les valeurs de retour, il y a des débats. Pour le passage de paramètres à des fonctions, même si je sais comment Rust fonctionne, je ne suis pas convaincu qu'un changement de sémantique par défaut serait avantageux pour C++
Titus Winters : souvent, le simple fait d'offrir un constructeur de mouvement règle le problème d'office.
Bjarne Stroustrup : je vous en prie, apportez-nous une proposition de terminologie
Arthur O'Dwyer : Giraffe Case. Pourquoi?
Bjarne Stroustrup : je préfère les minuscules et les _ mais pour les concepts, à un moment donné dans le passé, on a commencé à utiliser une autre forme. Que les nouveaux trucs soient mis en relief et visibles parce qu'ils sont nouveaux... est une mauvaise idée
Herb Sutter : j'ai des problèmes plus importants à régler (je paraphrase)
Marshall Clow : dans les intervalles, c'est un PascalCase pour les concepts du début à la fin pour le moment
(j'ai manqué une question sur le Feature Freeze pour C++ 20)
Q : la mécanique de standardisation semble avoir beaucoup changé depuis C++ 11. Est-ce que vous estimez que ça fonctionne? Que changeriez-vous?
Marshall Clow : avant C++ 11, nous avons livré une fois en huit ans; depuis, nous avons livré trois fois en sept ans. C'est un gain net.
Olivier Giroux : nous avons aussi essayé le processus des TS. Nous n'avons pas été terribles pour déterminer ce qui y va, et comment ça s'intègre au IS. Le rythme de livraison aux trois ans est une bonne idée, mais le comité n'est pas une entreprise. On se stresse beaucoup aux trois ans...
Ville Voutilainen : le désaccord sur scène à propos des TS et de leur succès ne veut pas dire que nous n'avons pas profité des TS pour constater des problèmes qui nous auraient échappé autrement.
Bjarne Stroustrup : je pense qu'intégrer quelque chose dans un IS entraîne plus d'action et de mouvement que les alternatives. Aussi, C++ 03 était bien mineur, donc C++ 98 à C++ 11, c'est un écart de 13 ans, et nous visions 2008 et nous avons été patients... Nous devons être plus agressifs
Herb Sutter : pour moi, les TS sont des branches et le IS est le tronc. C'est un outil. Les livraisons régulières envoient un message clair au marché et à nos usagers (applaudissements)
Marshall Clow : j'ai soumis une proposition pour C++ 14 (les searchers). Nous avions trouvé un bogue terminologique. J'ai demandé qu'on le retire, le temps que j'y pense et que je réécrive le tout. Ce qui est dans C++ 17, trois ans plus tard, est un bien meilleur design
Mathieu Ropert : le constat ce matin que auto est le plus faible concept me fait me demander si almost alyways auto est une bonne idée
Herb Sutter : ce que j'ai dit à CppCon 2014, à propos de almost always auto, est que ça nous force à initialiser. Le almost est même disparu depuis que C++ 17 a rendu Copy Elision obligatoire
Bjarne Stroustrup : les concepts clarifier le rôle des objets et apportent au texte la clarté qui échappe parfois avec auto pris isolément
Ville Voutilainen : j'ai proposé le recours à auto en tant que type de paramètre. À mon sens, les avantages sont nettement supérieurs aux inconvénients
Mathieu Ropert : alors on utilise auto?
Bjarne Stroustrup : on utilise les concepts (rires!)
JF Bastien : que retireriez-vous du standard si vous le pouviez?
Bjarne Stroustrup : je refuse de répondre. Cette question m'épuise
Herb Sutter : les macros
Titus Winters : CTAD. Je n'aime pas
Ville Voutilainen : je ne le retirerais pas, mais je le réécrirais : volatile. Je clarifierais aussi les constructeurs de copie
Olivier Giroux : volatile, thread_local... memory_order_consume!
Marshall Clow : CTAD... Je pense qu'on n'a pas bien compris les implications avant de l'accepter
Bjarne Stroustrup : ... CTAD était près selon moi, et je veux faire remarquer que les concepts peuvent le remplacer dans bien des cas
Q : un fork du langage?
Titus Winters : nous avons eu un std2 pour un bref moment... Cela dit, ça ne vaut jamais la peine d'aller dans cette direction. C'est une très mauvaise idée
Ville Voutilainen : nous en avons parlé à l'occasion... informellement... pour tuer l'idée. La stabilité est un major feature de ce langage
Q : à propos de constexpr. J'ai vu constexpr! passer dans les propositions. Peut-on déduire constexpr du type de retour d'une fonction?
Bjarne Stroustrup : le modèle est peut être résolu à la compilation, pas doit être... On peut forcer l'évaluation à la compilation par une utilisation dans un contexte constexpr.
Ville Voutilainen : pour la question, non, le type de retour n'impose pas constexpr.
(question sur les travaux de la fin de semaine sur les modules; Bjarne Stroustrup fait un résumé et Ville Voutilainen complète; sans faire de promesses, on vise toujours C++ 20; Olivier Giroux rappelle que les exécuteurs ont aussi reçu un examen détaillé durant la fin de semaine et sont extrêmement importants; le design est nettement meilleur, trop gros pour C++ 20, mais un sous-ensemble très humble est encore envisageable)
(c'est presque fini mais je dois y aller)
Fin de soirée tranquille. J'écris un peu à mon amoureuse, je retourne quelques courriels, et c'est l'heure de dormir un peu.
Je présente cet après-midi, et je dois être présent tôt à la demande d'Hana Dusíková qui m'a demandé un soutien de dernière minute (c'est sa première présentation officielle ici, même si son Lightning Talk de l'an passé a entraîné beaucoup de réactions). Debout, douche, courriels (quelques trucs à gérer à distance, particulièrement au Collège où mes ami(e)s de première session ont un examen en mon absence cette semaine, et font preuve de nervosité), puis je passe en revue mon matériel en vue de la présentation de cet après-midi. J'espère que les gens vont aimer; il y en a peut-être trop, mais on verra bien.
Avant la présentation formelle de Hana Dusíková, une présentation non-planifiée (du Open Content) occupe les lieux. Il y a beaucoup de gens déjà vers 7 h 45 alors que la présentation ne commence que vers 9 h, ce qui est bien pour cette session d'Open Content, mais sans vouloir leur enlever quoi que ce soit, je suspecte que les gens soient plus ici pour la présentation de 9 h justement.
Le présentateur n'a pas mis son nom sur la diapositive initiale. Semble que ce soit Matthew Flemming
Il parle d'un cas où le programme consomme énormément de mémoire (64 Go s'ils le peuvent), et où les Core Dumps sont massifs, ce qui leur prend une éternité. La présentation porte sur les petits Core Dumps partiels. Leur code fait de la persistence d'objets et parle directement à la mémoire Flash. Les Core Dumps doivent pouvoir être consommés par gdb une fois générés malgré leur format atypique.
Leur problème est que les trucs « normaux » ne fonctionnent pas dans leur situation, et que le système d'exploitation est hostile à leur approche. Il utilisé readelf -a core pour comparer les binaires qu'il générait et les Core Dumps jusqu'à ce qu'il en arrive à quelque chose qui se ressemble. Il présente le détail du format et montre ce dont il peut se passer tout en gardant le reste opérationnel.
Il parle ensuite de la gestiion des signaux avec des Signal Handlers, et de ce qu'il est possible de faire dans ces contextes (semble que les entrées / sorties soient permises)
La question qui suit est celle de déterminer ce qui doit aller dans le Core Dump. Il parle d'états par thread, de ce qui semble « intéressant » dans la mémoire (surtout en périphérie du lieu où le programme semble avoir brisé). Il procède par signaux pour la collecte, en utilisant SIGUSR1 qui est réservé pour usage dans le code client sur POSIX.
Sa gestion de mémoire semble artisanale : il part d'un estimé raisonnable, qu'il double ou triple au cas où selon le contexte... Faut dire qu'il a plus ou moins le choix, car les allocations dynamiques de mémoire sont illégales dans un Signal Handler.
L'air de rien, c'est amusant comme concept, écrire un programme qui gère la mort d'un autre programme... Un exercice pour le futur?
Sa gestion de terminaison est aussi... artisanale : il lance plein de threads, quand ils ont fini ils font for(;;) sleep(100); et ça se termine quand le thread principal tue le processus.
Il consulte plusieurs fichiers systèmes (des trucs dans /proc par exemple, comme /proc/self/maps) pour saisir les infos dont il a besoin. Il discute des formats. Beaucoup de travail, beaucoup d'artisanat. Il décide ce qui va dans le Dump sur la base des noms de fichiers
La discussion mentionne l'alignement à plusieurs reprises (certains trucs doivent être alignés sur 2 Mo, sur 4 Ko) et d'ordre des données pour générer un minidump correct.
La synchronisation des écritures est une préoccupation de la salle. Il se fie beaucoup au système d'exploitation. Une question sur les relations parent / enfant lors d'un fork() et sur la collecte d'informations subséquente est intéressante mais la réponse est très technique. Quelqu'un suggère de modifier le noyau tout simplement, mais le présentateur se dit d'avis que le rapport coûts / bénéfices aurait été désavantageux pour lui.
Il en arrive à des dumps qui sont en pratique environ un quart de la taille des Core Dumps réguliers
Ça se termine vers 8 h 40. Je bavarde avec Jean-Claude Bounthong qui était dans ma classe en fin de semaine (chic type!), et Shafik Yaghmour vient se joindre à nous pour la présentation.
Pour la vidéo, voir https://www.youtube.com/watch?v=QM3W36COnE4
Pour les diapositives, voir ceci
L'amie Hana Dusíková est nerveuse...
Hana Dusíková se dit ravie de voir combien de gens sont présents dans la salle. Elle se présente, puis présente les expressions régulières et ce qu'elles peuvent faire.
Hana Dusíková montre des exemples, graphiquement (ses diapos sont vraiment remarquables), et montre comment les exprimer avec std::regex, de même qu'avec C (c'est pas joli)
Hana Dusíková : le constructeur compile l'expression. C'est coûteux (vraiment coûteux), complexité exponentielle. On peut écrire un automate à la main, bien sûr, mais c'est pas amusant à entretenir ou à déboguer. On peut utiliser un générateur externe, mais c'est déplaisant.
Hana Dusíková présente sa technique pour générer les expressions régulières à la compilation. La plupart du temps, ça devrait fonctionner (on connaît souvent les patterns d'avance de toute manière). Sa syntaxe est essentiellement idéale, et utilise des string_view et des chaînes compile-time (le code idéal fonctionne pour C++ 20). En attendant, elle a des littéraux _ctre (Compile-Time Regular Expression)
Hana Dusíková montre une utilisation de _ctre.match dans un static_assert. Elle utilise un tuple comme valeur de retour pour les matches partiels
Hana Dusíková montre le code machine généré... Son code tient sur moins de cent lignes, celui de std::regex sur près de 20'000 lignes
Hana Dusíková : la gestion d'erreurs est courte (deux lignes pour un cas de pattern malformé, garanti)
Jason Turner : est-ce que ça fonctionne avec des littéraux bruts?
Hana Dusíková : oui. Des chaînes non-char aussi
Hana Dusíková : utilise la syntaxe habituelle, rien de spécial à apprendre
Hana Dusíková présente son Parser et explique comment cela fonctionne. Elle a un Parser LL(1) générique écrit à la main et génère des Expression Templates, qui sont ensuite évalués. Elle entretient (à la compilation) une pile de symboles et consomme l'entrée symbole par symbole. Une démonstration de la table d'actions / transitions est faite. Elle dit avoir réécrit la bibliothèque six fois avant d'en arriver à une solution élégante à son goût : ses symboles sont des classes vides et ses productions grammaticales sont exprimées presque de manière identique en utilisant des signatures de fonctions. C'est vraiment joli. Elle utilise les surcharges de fonctions comme levier de sélection.
Hana Dusíková représente une grammaire dans un struct, ce qui lui permet d'avoir une grammaire pour JSON, une pour Brainfuck, une pour...
Hana Dusíková modélise la pile avec une jolie liste de types et des signatures de fonctions encore une fois. Elle recommande de penser de manière fonctionnelle quand on essaie d'écrire du code à la compilation, avec (tail) recursion
Hana Dusíková montre qu'elle a construit ses chaînes de caractères à la compilation sur la base des propositions de Jeff Snyder et de Louis Dionne (p0732), utilisant CTAD pour simplifier la syntaxe.
Hana Dusíková : le code est auto-validant, et la compilation est
Q : que se passe-t-il si on donne des entrées malformées?
Hana Dusíková : ça se brise après suffisamment de niveaux de récurremce avec les limites du compilateur
Hana Dusíková montre ensuite comment elle construit les Expression Templates. Elle construit en pratique un type à partir d'une chaîne de caractères. Sa présentation graphique est limpide. Quand elle change l'expression régulière et regénère l'affichage live, il y a des applaudissements dans la salle
Hana Dusíková entre ensuite dans le détail de la génération des Expression Templates. L'étape suivante est la mise en correspondance avec une chaîne de caractères. C'est tout simple. Le matching d'une séquence ou d'une option est monadique.
Hana Dusíková aborde ensuite les captures et les fonctionnalités plus complexes (lookahead, look-behind...). Elle voulait les diapos compréhensibles
Hana Dusíková passe ensuite aux benchmarks. Les sources sont très semblables entre CTRE et std::regex, mais les différences en termes de vitesse sont remarquables. Elle traite en quelques secondes des fichiers qui prennent plus de 20 minutes avec std::regex sur certaines bibliothèques. Marshall Clow semble impressionné
Hana Dusíková recommande de réfléchir aux patterns, car la qualité des patterns a un gros impact sur la vitesse de traitement. On a du plaisir dans la salle
Hana Dusíková aborde ensuite les benchmarks de temps de compilation... Il se trouve que std::regex compile plus lentement que CTRE. Il y a des applaudissements dans la salle. On discute des objets mesurés (le temps de compilation est influencé par les patterns, évidemment). Évidemment, le caching fait que réutiliser les mêmes patterns est à coût nul
Hana Dusíková : utilisez la programmation fonctionnelle et la récursivité. Pensez fonctionnel. Faites confiance à votre compilateur (applaudissements nourris!)
Q : peut-on unifier compile-time et run-time?
Hana Dusíková : si std::regex était constexpr, on n'aurait pas besoin de ma bibliothèque. On peut utiliser CTRE dans godbolt (c'est une des bibliothèques offertes par défaut). Elle fait une démo devant nous. À -O3, son match tient sur une vingtaine de lignes de code machine
Q : avez-vous comparé avec Boost::Regex?
Hana Dusíková : j'ai peu d'expérience avec Boost. Je vais l'essayer. Question de temps.
Q : quelles sont les limites de votre approche?
Hana Dusíková : la longueur des lignes. Ce serait douloureux avec un gros fichier JSON par exemple
Pablo Halpern : j'ai été surpris de voir que tu pouvais faire le match à la compilation... Comment comparer avec une chaîne runtime?
Hana Dusíková : les fonctions constexpr vivent dans les deux mondes
Odin Holmes : c'est la chose la plus merveilleuse que j'aie vu en métaprogrammation (applaudissements!). As-tu essayé des trampolines?
Hana Dusíková : je ne connais pas la technique
Nicole Macuzza : as-tu essayé des extern template pour limiter l'exposition?
Hana Dusíková : tu peux utiliser des fonctions ordinaires
Mathieu Ropert : la limite est-elle la taille de la grammaire?
Hana Dusíková : non, la limite est la taille de l'entrée (Mathieu Ropert suggère un eval statique pour C++; on rit, mais la grammaire n'est pas LL(1))
Q : as-tu comparé avec Flex ou Bison?
Hana Dusíková : non, ils me font peur (rires!)
C'était rien de moins que remarquable. Je suis allé la féliciter et lui souhaiter un peu de repos, puis j'ai bavardé avec Shafik Yaghmour un peu (il est vraiment de commerce agréable).
Il y a des yogourts et des fruits ce matin, ça fait du bien. Hier, j'ai un peu manqué de carburant en fin d'avant-midi. Ces événements sont extrêmement physiques.
Pour la vidéo, voir https://www.youtube.com/watch?v=2YXwg0n9e7E
Pour les diapositives, voir ceci
Le keynote de ce matin est intéressant. Mark Elendt est un artisan du monde du cinéma et de la télévision (il travaille entre autres sur Game of Thrones) et il a ceci de particulier qu'il a remercié les artisan(e)s de C++ depuis C++ 11 lorsqu'il a gagné un oscar l'an dernier, du fait que le langage et sa progression leur a ouvert des portes vers de nouvelles techniques d'animation et a contribué au succès de ses projets.
Jon Kalb fait les annonces d'usage (sondages, code de conduite, comment ça va).
C'est Bryce Adelstein Lelbach qui présente Mark Elendt, avec la vidéo de son oscar présenté par Patrick Stewart.
Mark Elendt : notre logiciel est en C++, toutes nos programmeuses et tous nos programmeurs utilisent C++. Les gens du cinéma ont applaudi quand j'ai remercié WG21 car tout le monde y utilise C++
Mark Elendt : dans les années '80, quand Tron est sorti, il y avait une dizaine de boîtes de logiciel graphique et elles ont toutes contribué au film. Toutes sauf une utilisaient C (l'autre utilisait Lisp), et la plupart avaient du matériel sur mesure. On utilisait un Cray, une Vax, des fichiers de 5 Mo (en 1982!), etc.
Mark Elendt : j'ai joint la compagnie SideFX en 1989. Les outils étaient tous à la ligne de commande (il montre des exemples avec des polices de caractères, des effets et de la géométrie). Pour être un artiste, il fallait être technique. Tout roulait sur Unix et on utilisait | pour relayer des données d'un programme à l'autre
Mark Elendt : Houdini, notre produit, permet maintenant d'assembler un réseau de noeuds visuellement pour en arriver aux mêmes résultats. Les changements apportés aux graphes sont répercutés visuellement en temps réel. On peut aussi décomposer des équations compliquées (p. ex. : Navier-Stokes) en blocs modulaires pour les manipuler à la pièce
Mark Elendt : l'équivalent des commentaires dans notre code est des post-its virtuels. Nous avons des outils pour réorganiser les graphes et les rendre plus faciles d'approche (un peu un équivalent graphique de clang-format)
Mark Elendt : voir un réseau de noeuds permet entre autres d'identifier plus facilement les branches mortes. C'est un bénéfice auquel nous ne nous attendions pas
Nous avons droit à plein de démonstrations. Truc amusant : le graphe de code de leur outil est un objet avec physique, et certains créent des jeux avec les noeuds de code. C'est assez divertissant. Il discute de l'importance de convertir rapidement un nombre à virgule flottante de manière optimale; ce type d'opération occupe leur logiciel à plein temps
Mark Elendt : Houdini est la version C++ de leur produit traditionnel, surtout fait en C. Ils ont donc vécu cette conversion. La conversion s'est entreprise alors que le draft de la STL prenait forme (1994) et que Boost n'existait pas encore... Ils ont vécu cfront, les Template Repositories, les versions avec .h de fichiers comme iostream... et ont écrit des tas de classes à la main, classes pour lesquelles nous utiliserions celles de la STL aujourd'hui
Mark Elendt : tous les studios ont leur propres outils. Nous avons décidé de produire une plateforme de référence nommée VFX. Nous avons commencé à utiliser C++ 11 en 2016, avec g++ 4.8. C'est ce qui fut le plus grand changement; il y a eu de la résistance de la part des studios (certains voulaient encore utiliser register), et certains ont choisi de rester sur C99. En 2018, nous commençons à utiliser g++ 6 et C++ 14. Plusieurs studios participent encore à VFX. L'académie qui donne les oscars techniques fait plus que distribuer des statues; c'est un groupe qui comprend des scientifiques et des artistes. L'Academy Software Foundation (ASWF) va même plus loin que VFX maintenant.
Mark Elendt : nous avons commencé à mettre certaines de nos classes maison à la retraite (p. ex. : nos atomiques maison) et à les remplacer par std::atomic. Utiliser des méthodes marquées DEPRECATED nous aide dans la période de transition. Éventuellement, quand les API concordent nous remplaçons notre classe par un using vers celle du standard. Il nous montre des manoeuvres très C dans leurs classes, qui montrent le chemin fait / à faire. Il dit que leur UT_Array est plus rapide que vector lors d'un redimensionnement (ils utilisent realloc), mais ça ne fonctionne pas sur des types non-triviaux (ceux qui ont des invariants cachés, en particulier). Il se dit ravi de voir std::trivially_relocatable faire son chemin vers le standard (c'est Arthur O'Dwyer qui va être content!)
Mark Elendt parle ensuite des classes de géométrie spécialisées de sa bibliothèque. Il parle de AoS / SoA (c'est mes étudiant(e)s de la fin de semaine qui seront ravi(e)s!). Leur graphe tient à jour des caches de géométrie. Ils utilisent Copy-on-Write pour les gros tampons (ils ont beaucoup de points et de primitives par forme; on parle de dizaines de millions dans chaque cas). Quand le changement se limite à quelques points, ils utilisent des Paged Arrays et visualisent des sous-ensembles disjoints de données, et utilisent en pratique des paires début,fin de pointeurs sur les données réelles
Mark Elendt : pour les chaînes de caractères, il y a un risque fort de duplication de chaînes identiques. Ils utilisent des StyleSheets mais les usagers en mettaient partout et ils se retrouvaient avec 15 Go de texte. Ils ont migré vers un StringHolder (paires hash / texte) avec compte de références intrusif, et font des partages à la pièce (ce sont des string COW). Un singleton sert de dépôt partagé en arrière-plan
Mark Elendt : ils ont développé plusieurs classes de perspectives sur les StringHolder, pour modéliser les comportements souhaités. Ils ont réduit les allocations de mémoire par un facteur de 20, et malloc() est un goulot d'étranglement dans leur code. Ils ont réussi à faire un littéral _sh constexpr incluant le hash
Mark Elendt : ils ont fait des erreurs (de l'héritage partout, pensant bien faire; suivre quelques modes). Il recommande un peu de réflexion et de modération. Ils comptent continuer la modernisation du code et sa standardisation. Il recommande non pas d'optimiser de manière hâtive, mais de penser la vitesse à même le design. Il recommande aussi d'utiliser les templates... quand c'est pertinent (les fichiers temporaires générés par g++ 6 pour leur code dépassent 6 Go!). Enfin, il recommande la méfiance envers tout, y compris son propre code
Q : comment choisir les bonnes technologies / les bonnes pratiques?
Mark Elendt : je ne sais pas. On se trompe encore. J'ai abusé de auto, personnellement. Idem pour la programmation générique
Q : devrait-on ajouter des types géométriques à la bibliothèque standard?
Mark Elendt : c'est un problème difficile
Q : pourquoi votre entier atomique est-il un template?
Mark Elendt : contrôle sur la taille
Q : utilisez-vous beaucoup de GPU pour votre code C++?
Mark Elendt : on utilise surtout OpenCL
Q : je travaille sur CUDA. Comment pourrions-nous vous aider?
Mark Elendt : je vais y réfléchir
Q : quelle est la différence entre votre string_ref et std::string_view?
Mark Elendt : une connaissance intrusive du substrat
Q : comment profilez-vous de gros outils comme ceux-ci?
Mark Elendt : j'utiliser Google Profile. D'autres préfèrent VTune
Q : est-ce que vous êtes satisfaits de ce que les optimiseurs vous offrent présentement?
Mark Elendt : oui. Nous utilisons parfois des intrinsèques. Les compilateurs sont excellents
Q : quelles optimisations faites-vous vous-mêmes?
Mark Elendt : nos propres allocateurs, incluant notre propre malloc() et notre propre allocateur de petits objets. Nous avons aussi un stack_buffer
Q : optimisez-vous le réseau de noeuds lui-même? Je comprends qu'il est Turing-Complete... (je manque la réponse, il se fait tard et il y a du bruit)
(je manque beaucoup de ce qui se dit dû au bruit des gens qui vont dîner)
Je vais me prendre un sandwich avant d'aller à la rencontre du comité de programme. Je croise Zoetica Ebb qui prend des photos de la longue file sinueuses de fans qui attendent que Bjarne Stroustrup se présente pour une séance de signatures de ses livres.
Je pique une petite jasette avec Kate Gregory, puis avec Ben Deane (on présentera en même temps lui et moi, juste après la rencontre).
Bryce Adelstein Lelbach prend la scène, puis passe à Jon Kalb
Jon Kalb : évitons les références au suicide (Enough Rope to Hang Ourselves). Surtout dans les titres
Jon Kalb : évitons la politique, soyons prudents avec les références culturelles
Bryce Adelstein Lelbach : mettons-le dans le code de conduite, ou référons à ce document
Bryce Adelstein Lelbach : nous déménageons l'an prochain. Même format, mais nouveau lieu. Ça va impacter la présence (certains ne viendront plus, certains viendront désormais). Il sera important de bien passer le mot l'an passé
Bryce Adelstein Lelbach : nous recevons approx. 200 soumissions, nous en acceptons plus d'une centaine, mais les soumissions ne croissent pas en nombre aussi vite que la participation. Nous souhaitons maintenir le niveau de qualité
Jon Kalb : j'ai l'impression que la qualité est légèrement en haute par contre. Peut-être sur la base des exemples du passé, disponibles en ligne
Bryce Adelstein Lelbach : les gens comprennent peut-être mieux ce qu'on veut
Jens Weller : je pense que vous devriez tendre la main un peu plus à l'audience. Il y a un chevauchement entre comité de programme, comité de standardisation et présentatrices / présentateurs.
Jon Kalb : as-tu des idées? On passe par Twitter, le site Web, Facebook, les balados...
Jens Weller : à ma conférence, j'ai un New Speakers Track. J'essaie de « développer de nouveaux talents » avec ça. J'approche les gens qui font des Lightning Talks pour l'année suivante, généralement
Bryce Adelstein Lelbach : devrait-on aussi envisager un Female Speakers Track? Je ne sais pas...
Jon Kalb : cet événement appartient à la communauté. Invitez des gens à participer et à soumettre
Kate Gregory : dire à des gens de participer et de soumettre, leur parler directement, ça fonctionne. Faut le faire. Surtout pour les gens qui font partie de communautés sous-représentées
Jon Kalb : on a Submission Advice...
Kate Gregory : quelqu'un écrit, dit qu'elle ou qu'il pense présenter sur le sujet XYZ. Quelqu'un d'autre dit « Bonne idée, veux-tu qu'on en parle? » et fait de l'accompagnement. Ça fonctionne bien! Écrire un Abstract est difficile; on peut les aider à faire leur chemin
? : je vais à des conférences vastes (7K+ participant(e)s) qui ont des Tracks thématiques, annoncées d'avance
Bryce Adelstein Lelbach : on essaie de répartir les propositions par thèmes post-réception. On peut commencer à réfléchir à une catégorisation a priori
Jon Kalb : c'est difficile de prédire ce qui entraînera des soumissions d'une année à l'autre
Peter Sommerlad : on est peut-être victimes de notre succès. Les présentations sont de très haute qualité, et ça peut sembler un peu casse-gueule pour qui ne s'est jamais risqué à présenter devant un group de grande taille
Ben Deane : nous savons sur ce comité que les présentateurs expérimentés c'est une chose, mais qu'on veut du sang neuf. On devrait peut-être juste le dire : on cherche de nouvelles présentatrices et de nouveaux présentateurs
Jens Weller : l'absence un an de présentations sur un sujet peut donner l'impression que le sujet n'est pas populaire. Aussi, nous avons plusieurs présentations de type « tour d'ivoire », mais trop peu sur des outils et des bibliothèques susceptibles d'être utilisées le jour même. Pourtant, c'est un très gros colloque, et il y a de la place
Georgy ? : c'est ma première présence ici. Ma compagnie nous a offert de venir gratuitement, et plusieurs avaient peur, se sentant exclus par une communauté exclusive. Ici, j'ai vu des présentations sur les GPU, mais pas très focalisés. J'ai l'impression que les gens craignent de ne pas pouvoir appliquer ce qu'ils vont apprendre ici dans le cadre de leur travail
Bryce Adelstein Lelbach : nous nous attendions à accueillir des débutant(e)s la première année, mais nous nous sommes trouvés face à des présentations et à une audience allant d'intermédiaire à avancé
Dan ? : il y a aussi les gens qui font quelque chose, mais rien de spectaculaire... Pourquoi venir en parler ici?
Jon Kalb : je pense qu'il y aurait des gens dans la salle
Bryce Adelstein Lelbach : on pourrait clarifier qu'on veut des trucs en C++ autant que des trucs sur C++
Aaron ? : je pense qu'il pourrait être utile de résoudre le problème du recrutement de sang neuf en suggérant une thématique pour l'une des Tracks au moins
Bryce Adelstein Lelbach : on pourrait probablement le faire
Alex Davis : je pense qu'on pourrait ajouter des des dimensions. Intercaler les classes avec l'événement. Plus de Workshops
Jon Kalb : j'adorerais ça... mais c'est très difficile à organiser. La gestion du temps, les bogues logiciels... J'ai imploré les gens de LLVM pour un Lets Hack LLVM, sans succès
Bryce Adelstein Lelbach : mais si on avait plus de sessions interactives?
Kate Gregory : on pourrait avoir une salle réservée, et un instructeur / un entraîneur qui reçoit plusieurs petits groupes durant la semaine
Serge ? : je trouve que la communauté est très inclusive. J'ai été accepté pour une présentation à ma première soumission, j'étais un inconnu, on m'a inclus dans le comité de programme. En retour, le niveau moyen des présentations ici est extrêmement impressionnant et intimidant, et je comprends qu'un(e) débutant(e) vive des craintes. Je pense qu'on pourrait avoir des sessions pratiques pour gens moins avancés
Bryce Adelstein Lelbach : est-ce intimidant d'offrir l'option de ne pas se faire enregistrer? Ça arrive très, très rarement
Peter Sommerlad : et si on avait des séances courtes, enregistrées, mais surtout pour fins de coaching et de rétroaction. Aussi, que diriez-vous d'une i pour la modernisation (de code C, de vieux code C++)?
Bryce Adelstein Lelbach : on a déjà fait ça à C++ Now et ça s'était bien passé
? : et si les membres du comité invitaient des gens directement?
Bryce Adelstein Lelbach : on peut essayer
Jens Weller : on pourrait avoir une Track d'autre chose quue des présentations. Par exemple, une pour discuter sur des sujets spécifiques. On tient ça dans un lounge; ici, il nous manque des lieux plus tranquilles, plus relaxes
Timur Doumler : j'ai beaucoup entendu ça aussi. C'est difficile de préparer une présentation ici (bruit, gens)
Kate Gregory : c'est controversé; il y a des gens qui se cachent dans ces pièces car les facilités tendent à être différentes
Bryce Adelstein Lelbach : on choisit délibérément de en pas tracers de distinction entre classes d'individus ici (speakers / non-speakers)
Jon Kalb : ici, philosophiquement, on ouvrirait la pièce à tous
Jeff Trull : devrait-on clarifier le sens des nombres qu'on appose sur l'évaluation des présentations?
Jon Kalb : cette année, j'ai commis une bourde en mettant à jour le site Web de l'événement. C'est ma maladresse
(on réexamine les consignes)
Bryce Adelstein Lelbach : nous avons eu plus de propositions de sessions de 30 minutes cette année. Elles sont groupées pour fins de logistique. On voudra savoir comment ça s'est passé
Alex Davis : pour ce qui est de l'audience, je n'ai rien vu pour éduquer les gens sur le mouvement, les catégories de valeurs, le forwarding...
Jon Kalb : il y a une grosse différence entre un colloque et une formation. Les gens qui ont besoin de formation tendent à ne pas venir ici; pour ces besoins, mieux vaut engager une formatrice ou un formateur
Serge ? : devrait-on offrir une version européenne?
Bryce Adelstein Lelbach : il y a déjà Meeting C++ et ça fait très bien le travail
Mark : est-ce que vous pensez que les gens sont rébarbatifs à donner des chiffres négatifs? Si oui, une idée serait de remplacer la plage allant de -2 à +2 par une plage allant de 1 à 5
Jens Weller : il serait important de rappeler aux gens qu'ils votent au « nous », pour la communauté, pas au « je ».
Michaël ? : et si on remplaçait les nombres par des catégories?
Bryce Adelstein Lelbach : j'ai un système du genre pour la sélection finale. C'est une bonne idée. Peut-être « qualité » et « pertinence »
Georgy ? : devrait-on demander aux gens s'ils viendront, que la proposition soit acceptée ou pas (s'applique aux voteurs)?
Bryce Adelstein Lelbach : je pense qu'on doit aussi faire attention aux erreurs du passé, et ne pas bloquer quelqu'un qui aurait eu une mauvaise réception
Kate Gregory : faudrait peut-être voir s'il y a une corrélation entre les votes élevés et le succès des notations
Bryce Adelstein Lelbach : on a souvent de belles surprises de la part de gens moins connus... et de moins bonnes réactions à des propositions cotées de manière très élevée dû à la réputation des présentatrices et des présentateurs
Jon Kalb : on a beaucoup de nouveaux visages... mais on a beaucoup de gens qui ne reviennent pas, mais on croit comprendre que les compagnies envoient les gens en rotation
Ben Deane : on devrait relancer tous les gens présents ici dès mai l'an prochain, pour les encourager à vendre l'idée de revenir et d'en amener d'autres avec eux
Alex Davis : sait-on qui vient en payant de sa poche et qui est financé par son entreprise?
Bryce Adelstein Lelbach : ce serait intéressant à savoir
On arrête les travaux vers 13 h 30. Je vais me préparer pour ma propre présentation
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Je me suis installé, j'ai fait des tests de sons, j'ai blagué avec les gens. Il y avait beaucoup de gens, mais j'ai perdu des gens en chemin (était-ce parce que j'ai mal livré, ou parce que les gens se sont aperçus que c'était pas pour eux? Je ne sais pas).
J'ai eu un peu d'interactions avec Jonathan Caves (toujours pertinent), John McFarlane et Aaron Ballman en particulier, mais peu de questions après la présentation (quelques-unes, mais plus en privé qu'en public). Pourtant, j'ai eu plusieurs bons commentaires le reste de l'après-midi. Je ne sais pas trop quoi penser... Il m'a semblé que c'était pas si mal.
Pour la vidéo, voir https://www.youtube.com/watch?v=IupP8AFrOJk
Pour les diapositives, voir ceci
Patricia Aas prend le relais.
Patricia Aas : une faillite d'une boîte canadienne hier a causé une brèche de sécurité. Faut vivre avec une certaine quantité de risque.
Patricia Aas : la sécurité est un champ difficile. Nous vivons dans « le vrai monde », nous devons avancer un pas à la fois, et planifier.
Patricia Aas : il faut une « security hotline » pour ces moments où un problème est découvert. C'est compliqué à gérer (politesse, courtoisie, professionnalisme... Les gens qui nous rapportent un problème nous rendent service, alors faut être reconnaissants)
Patricia Aas : je ne recommande pas un Bug Bounty. L'argent est un détail; ce qui est compliqué est de gérer les gens qui doivent gérer les rapports livrés par des tiers, et séparer le bon grain de l'ivraie.
Patricia Aas : qu'est-ce qu'un système? Qu'est-ce qu'une vulnérabilité? Je vais examiner quelques scénarios typiques de gestion des risques
Patricia Aas : Unable to Roll Out Fixes. C'est une situation très répandue. Certains composants / certains systèmes échappent à notre contrôle. Les sources peuvent être disparues. La compagnie à l'origine du produit peut avoir fait faillite. Le problème peut être sur notre réseau. Les ennuis :
Patricia Aas : les trucs sur l'IdO (les jouets, les trucs comme MIRAI). Les solutions sont les mises à jour automatiques, une plus grande variété de mots de passe par défaut (mais rien de prévisible comme la Mac Address), et imposer au client de changer leur mot de passe. Le Shelfware (code fermé, abandonware, pas de contrat d'entretien). Les solutions sont de prendre un contrat d'entretien, changer de fournisseur, le faire vous-même...
Patricia Aas : il vous faut un environnement de Build. On peut aussi faire des patches binaires, mais c'est difficile. Vos besoins, votre rythme peuvent ne pas concorder avec ceux de votre fournisseur.
Patricia Aas : certains systèmes devraient imposer qu'on se déplace pour les arranger. Les trucs de vote électronique, par exemple. L'accès à distance est une chose dangereuse.
Patricia Aas : No Control Over Dependencies. Il arrive qu'on n'ait pas d'inventaire, pas de routine de mise à jour, pas d'audit. C'est arrivé à Equifax (vulnérabilité dans Apache Struts 2), où il aurait fallu avoir un audit continu des dépendances; dans OpenSSL (Heartbleed), où il aurait fallu contrôler l'environnement de production; dans Left-Pad (une bibliothèque mini-Js qui a été supprimée, mais dont des tas de gens dépendaient de manière transitive... Ça a brisé Babel, Node.js et combien d'autres trucs), où il y avait des dépendances superflues. Faut du contrôle sur nos dépendances, à même nos processus
Patricia Aas : The Team is Gone. Équipe locale, consultants, post-mise à pied, post-impartition, etc. Mieux vaut avoir un fork, une prise en charge. Utilisez ce que vous faites : Eat Your Own Dog Food. Investissez-vous dans votre produit.
Patricia Aas : It's in Our Code. C'est la meilleure situation, car on a du contrôle et la capacité de livrer. Le problème est souvent dans le marketing! Par exemple, le Keeper Password Manager qui laissait fuir les mots de passe. Poursuivre le journaliste qui rapporte le bogue est une grave erreur, qui vous coûtera de la crédibilité. Un incident semblable est arrivé sur gitlab.com a été géré avec transparence. Leurs backups ont échoué l'un après l'autre, mais le processus fut public, et plusieurs ont choisi de migrer vers cette plateforme : ils ne se cachent pas, et ils testent leurs backups. Un problème bien géré montre culture d'entreprise et éthique
Patricia Aas : My Boss Made Me Do It. Que faire quand le bogue est un feature... Ça peut même être illégal. Il y a des cas où le patron exige le geste répréhensible, mais la programmeuse ou le programmeur va en prison pour avoir posé le geste. Le cas de mSpy est particulier : l'information perdue avait cette propriété que les usagers ne savaient pas qu'elle existait. Protégez votre équipe, votre compagnie. Vous avez des droits, les équipes peuvent prendre les coups collectivement, prenez soin de votre réputation, et utilisez des leviers légaux si nécessaire
Patricia Aas : cas récents : Dragonfly chez Google (moteur de recherche chinois avec leviers pour le gouvernement chinois). Maersk : NotPetya (un rançongiciel qui s'est répandu dans le monde entier)
Patricia Aas : reste à s'occuper de l'interface usager pour rapporter les problèmes. Les usagers ne liront pas du texte, seront aveuglés par les erreurs, et voudront qu'elles disparaissent. Error Blindness. Just Click Next. Make It Go Away.
Patricia Aas : être digne de confiance est notre responsabilité
Pas de questions, pourtant c'était intéressant. C'est presque rassurant. Je suis allé la féliciter rapidement : elle et moi échangeons à l'occasion par écrit, et j'aimerais bien qu'elle s'implique sur WG21. Elle est brillante et a une perspective un peu différente, qui nous aiderait à certains égards.
Pour la vidéo, voir https://www.youtube.com/watch?v=oK7hdBoxRcs
Pour les diapositives, voir ceci
Je suis arrivé un peu en retard car il n'y avait que cinq minutes entre la présentation de Patricia Aas et celle-ci, et j'ai voulu prendre une bouchée de quesadillas (il y avait une file). Petit soulagement, j'ai eu de bons commentaires sur ma présentation en attendant.
La salle est pleine alors je m'asseois par terre. Il y a déjà une dizaine de diapos de traitées.
Stephen Dewhurst fait un exposé sur la manipulation de listes de types. C'est un sujet que je connais bien, mais c'est un bon présentateur, il est drôle et il a de l'expérience alors je vais peut-être voir quelques trucs amusants. Il montre comment dépaqueter de manière monadique des séquences variadiques, comment manipuler des séquences d'indices. Il fait la démonstration qu'on peut passer de séquences de types à séquences d'indices, et faire de même avec des séquences de templates
Stephen Dewhurst discute de métaprédicats, et montre comment il est possible de transformer un prédicat sur un type en un prédicat sur un indice
Stephen Dewhurst : you don't want to be WET and Write Everything Twice. You want to be DRY. (je vais la retenir)
Stephen Dewhurst : j'ai manqué le début, mais son cas d'utilisation principal semble être un partition<class TL, template<class>class Pred> ce qui explique (je présume) l'intérêt de la conversion en indices pour obtenir un point de partition
Stephen Dewhurst fait un plaidoyer pour using et sa beauté. Là-dessus, on se rejoint; c'est un truc difficile à expliquer à des débutant(e)s, mais d'une utilité indéniable
Truc amusant, il s'est amusé à essayer d'exprimer une numérotation de Gödel du système de types de C++. Aussi, un peu comme je fais de la publicité pour le refuge de chats de mon amoureuse Za, il fait de la publicité (discrète) pour la campagne politique de son épouse en plaçant ses diapos sur le site de ladite dame.
J'ai profité du moment entre cette présentation et la prochaine pour parler quelques minutes avec Ludo, qui a eu un bon premier rapport de la maternelle, Vayda qui a eu un bon examen de mathématiques, et Za qui est toujours aussi belle. Pour le reste : un verre de glace et de citron, puis on recommence.
Pour la vidéo, voir https://www.youtube.com/watch?v=7Jk1a4cnukQ
Pour les diapositives, voir ceci
C'est un sujet controversé, et il y a du monde ici.
Guy Davidson se présente. Ce sera son anniversaire vendred, 51 ans! Il nous tracera un historique que cette bibliothèque graphique mal aimée qu'il porte à bout de bras depuis des mois.
Guy Davidson fait une démo « live » du jeu de la vie de Conway. Son code est 100% portable et c'est joli à l'écran. Le main() fait trois lignes et comprend deux callbacks tout simples. Le travail se fait dans la fonction qui rafraîchit la grille, puis les cellules. Il survole le code, c'est lisible pour l'essentiel. On peut enseigner ça au Collège pour qui est en mesure de faire de la géométrie 2D. Le jeu complet tient sur 200 lignes de code source. https://io2d.org
Guy Davidson enchaîne avec un historique des outils d'affichage et des API de dessin à l'écran. Il a une photo du PDP-1, entre autres. J'apprends que Logo a été écrit en Lisp. Le premier standard d'affichage, GKS, remonte aux années '80. Postscript remonte à 1994. OpenGL a 26 ans aujourd'hui, et il y a des gens plus jeunes que ça dans la salle. Les API graphiques les mieux connues sont listées en ordre d'apparition, à partir de SDL en 1998 jusqu'à Vulkan en 2016.
Guy Davidson : pourquoi io2d alors? L'un des problèmes de toutes ces bibliothèques est de choisir laquelle utiliser, et l'installer. SG15 peut régler ces problèmes à lui seul.
Guy Davidson fait des quiz artistiques de temps en temps. Il est drôle
Guy Davidson aborde ensuite la question de l'installation. Originalement, io2d reposait sur Cairo, qu'il fallait installer d'abord. Fallait aussi GraphicsMagick, Boost, Libpng, gcc 7+, CMake et libc++... C'est réglé depuis hier! Avec Windows, vcpkg suffit (vcpkg install cairo suivi de vcpkg install graphicsmagick), et il faut apt sur Linux. Il y a un peu de configuration à faire avec CMake ensuite. C'est ... frustrant. Faut réduire le prix d'entrée en C++
Guy Davidson passe aux sprites. Il fait voler des photos de chats. On regarde le code ensemble.
Guy Davidson suit avec des considérations de télémétrie. Il y a un outil sympathique pour ça. On regarde les sources.
Guy Davidson : on regarde un cas de Maps (à la Google Maps), avec les divers trucs qui s'y affichent (chemins de fer, route, plans d'eau, etc.). Il utilise Boost::asio et Boost::beast pour obtenir les données et parler à OpenMaps
Guy Davidson : des rochers dans l'espace (un clone d'astéroïde). Il nous fait une petite démo, puis on regarde le code. Il fait remarquer que le standard comprend plusieurs fonction mathématiques poussées mais rien sur la géométrie 2D.
Guy Davidson : on a un jeu simple et amusant, même si c'est pas un géant 3D hyper complexe.
Guy Davidson : quelles sont les directions futures alors? Écrire des exemples, entre autres. Il cherche des démonstrations sympathiques. C'est une bibliothèque pour les 80% (pas les spécialistes). Écrire une bibliothèque mathématique ou de rendu. Il est possible de s'en sortir en utilisant la proposition à titre de référence (p0267).
Guy Davidson : on veut aussi du texte, et éventuellement une standardisation. Peut-être une soumission à Boost. Il dit suivre les travaux de SG15 avec attention
Mathieu Ropert : je suis triste qu'on veuille standardiser quelque chose faute de package manager.
Guy Davidson : la vraie raison est qu'il n'y a pas de solution normale et standard pour les affichaegs graphiques
Mathieu Ropert : est-ce que l'échec des API précédentes était l'absence de standardisation?
Guy Davidson : il y avait pluieurs problèmes différents
Q : comment gérez-vous les erreurs?
Guy Davidson : on a une interface duale (exceptions, codes d'erreur), mais il faut savoir qu'il y a peu de zones de risques. J'aimerais bien que les exceptions statiques de Herb Sutter se concrétisent.
Du bon boulot. Je vois qu'un groupe super sympa, IncludeC++, auquel je participe parfois en périphérie faute de temps, a un souper ce soir. C'est à toutes fins pratiques mon groupe d'ami(e)s. Cela dit, je n'avais pas réalisé qu'il fallait s'inscrire et c'est plein au resto, alors je marche avec eux et je leur souhaite un bon souper. Ce sera du thaï pour emporter et un repas à la chambre de l'hôtel ce soir, mais c'est pas dramatique, je serai plus attentif aux messages la prochaine fois. Je vais en profiter pour fermer l'oeil quelques minutes, avant de revenir pour le panel sur les systèmes embarqués.
Au réveil, j'ai pris un peu de nouvelles de mon amoureuse, puis j'ai constaté que nous n'étions pas encore arrivés à trouver une date qui conviendrait à tous les intervenants pour ma défense de thèse, alors je suis allé ajouter quelques options et suggérer un « plan B » si jamais ça ne fonctionne pas. J'essaie fort de ne pas m'absenter un jour où j'ai des étudiant(e)s de première session avec moi, mais il se peut que je n'aie pas le choix. C'est bête, car plusieurs dates fonctionnent presque, mais faire concorder plusieurs horaires compliqués n'est pas une mince tâche.
Petite jasette avec Timur Doumler en marchant vers le Meidenbauer, puis je me sers un verre de glace et quelques fruits séchés avant de me rendre dans la salle où se tiendra le panel sur les systèmes embarqués.
Sur la scène, l'illustre Dan Saks, son fils et successeur technique Ben Saks, le toujours divertissant Odin Holmes et Andrew Sloss que je connais moins. C'est Brett Searles qui a le plaisir d'animer le tout. J'étais sur ce panel l'an dernier, mais je ne suis pas fâché de prendre une pause pour cette fois. J'en ai beaucoup.
Brett Searles se présente et fait se présenter les autres. Dan Saks aime bien utiliser C++ pour modéliser le matériel. Odin Holmes a beaucoup programmé en assembleur et ne voyait pas l'intérêt de faire du C car c'est presque aussi dangereux; il a démarré la conférence EmboC++ pour explorer cette facette de la programmation. Ben Saks vise à appliquer le C++ moderne aux systèmes embarqués. Andrew Sloss fait de la recherche et enseigne les systèmes embarqués à l'université de Washington, mais s'intéresse aussi beaucoup au futur des langages de programmation, en particulier l'apprentissage automatique.
Brett Searles suggère aux gens intéressés de s'impliquer dans SG14. Ben Saks ajoute que c'est un groupe populaire et où il y a de la participation en masse.
Q : il y a quelques années, Dan Saks a donné son keynote où il disait If you're arguing, you're losing. Comment aménager du code C++ pour qu'elle collabore bien avec du code C hérité du passé?
Dan Saks : d'abord, faut observer la règle de base : if it's not broken, don't fix it. Faut identifier ce qui mérite d'être fixé. Ensuite, faut évaluer les impacts, les conséquences. Il y a toujours un ensemble de ressources, typiquement représentées par un struct, qui se prête à une forme de refactorisation, puis il faut faire des tests de régression. Les objets mal structurés sont des opportunités. Les groupes de fonctions / de macros associés à ces struct sont des lieux d'exploration. Peut-on profiter d'un destructeur pour nettoyer des ressources?
Andrew Sloss : un des trucs difficiles est de comprendre ce que le code d'origine est supposé faire; le transférer en C++ est une occasion de mieux le comprendre. C'est particulièrement important d'en profiter à titre d'expérience d'apprentissage, pour les systèmes Safety-Critical. Il arrive qu'une ligne apparemment sans valeur initialise la DRAM toute entière, car le matériel est parfois une entité très étrange pour des gens de logiciel.
Brett Searles : le contrôle des accès aux données facilite la refactorisation.
Ben Saks : il est tentant de chercher à appliquer toutes les nouveautés de C++, mais quand on vient du monde C « vanille », mieux vaut faire des pas plus humbles. Le faire compiler en C++ est une première étape; y aller de petits pas, graduellement est une bonne suite. Faut pas sortir les gens trop radicalement de leur zone de confort.
Odin Holmes : toucher du code hérité est délicat. Il est probable que le vieux code C n'ait pas beaucoup de tests unitaires, car c'est pas simple à faire en C. Transformer des macros en fonctions constexpr est une bonne idée car tu peux alors tester le code C et le code C++. Faut faire attention aux occurrences du mot clé volatile, car il se cache probalement des bogues dans ces zones.
Q : qu'est-ce qui est facile / difficile / impossible dans le monde des systèmes embarqués aujourd'hui?
Andrew Sloss : Arduino est un point de départ intéressant pour expérimenter. Le meilleur point de départ est un Bare Board sans le moindre logiciel installé, ou encore travailler avec une nouvelle puce (on ne sait pas toujours si elle fonctionne!)
Dan Saks : la question est de savoir ce que tu veux faire (la personne ayant posé la question ne sait pas vraiment). Quand j'ai commencé, le premier Board que j'ai utilisé m'a été prêté par Andrew Sloss et venait avec des exemples en C, que j'ai réécrits en C++ de manière incrémentale. Il y a quelques livres disponibles sur le sujet. Ben Saks et moi donneront un cours ici sur ce sujet à la fin de la semaine.
Andrew Sloss : le plaisir que tu vas prendre à passer des heures à faire clignoter des lumières... personne ne le comprendra (rires!)
Ben Saks : en fait, programmer sur une plateforme embarquée n'est pas radicalement différente de la programmation convenionnelle, du moins au début. Quand on frappe un truc qui ne fonctionne pas (un volatile qui ne semblait pas apparent, par exemple), ça devient amusant
Q : mon équipe fait de la vision robotique sur une plateforme embarquée (Oculus Rift), alors que notre équipe soeur travaille plus près du matériel et fait tout en C. C'est pas dramatique, mais notre vie serait plus agréable si leur bibliothèque était en C++. Ils écrivent du beau C cela dit, bien structuré. Je vois leurs limites, mais ils ont de la discipline et ça fonctionne.
Odin Holmes : en s'approchant du matériel, le facteur « temps » devient important, et le facteur « mémoire limitée » aussi (faut traiter les débits entrants à temps). L'encapsulation forte n'est pas toujours pensée en termes de temps. Nous ne savons pas exactement comment parler de déterminisme dans la bibliothèque standard. Je ne peux pas prendre un verrou dans un service d'interruption, par exemple.
Dan Saks : j'ai l'impression que tu souhaites les convaincre de réécrire leur code C, de qualité, en C++... Le bouton pour faire cela n'existe pas. Je ne serais pas convaincu non plus; faut qu'il y ait un retour sur l'investissement pour que ça vaille la peine. C'est probablement à toi d'écrire cette couche, et de faire ressortir un gain, par exemple en termes de robustesse d'interface, en termes de vitesse, ou en termes d'identifier les erreurs à la compilation. (Brett Searles et Andrew Sloss parlent de pédagogie; un membre de l'audience mentionne que la programmation privée / publique par convention peut être prise en charge par le langage).
Q : plusieurs compilateurs embarqués ne sont pas à jour, en C comme en C++. Que fait-on avec ça?
Andrew Sloss : il y a souvent des règles fermes comme « aucune allocation dynamique », qui mènent à l'écriture de code très... conservateur.
Dan Saks : les outils de développement pour systèmes embarqués tendent à être de cinq à dix ans en retard sur les autres. Par contre, il y a des caractéristiques de C++ qui seront partout présentes : constructeurs, destructeurs, classes, contrôle d'accès... On commence la migration par là.
Q : et les autres outils, comme un IDE ou un débogueur...?
Dan Saks : j'avais l'impression justement que la compétition dans ce milieu se faisait surtout sur la base de ces outils plus que sur le support du langage dans son acception plus moderne. Andrew Sloss ajoute que c'est probablement leur marché.
Odin Holmes : au bureau, on utilise g++, CMake, gdb, l'éditeur de JetBrains... Je pense que les débogueurs sont pas mal, mais je préférerais trouver les bogues à la compilation, ou dans des tests unitaires.
Q : nous avons une base de code que nous devons compiler pour plusieurs processeurs. Nous écrivons du code C++ 98. Le plus récent compilateur commence à supporter C++ 11. Pensez-vous qu'on peut commencer à migrer à C++ 11?
Dan Saks : Ben Saks et moi faisons de la formation, et nous étions limités à C++ 03 jusqu'à cette année. C'est la première année que notre dernier client résistant a accepté de migrer à C++ 11. Enfin. (on fait un sondage rapide et ça semble être l'expérience de la salle).
Q : le mouvement est-il utile?
Odin Holmes : oh oui! Il donne un exemple avec un gestionnaire de ressources avec une liste munie d'une gestion intrusive (il prend des demi pointeurs, et utilise le reste des bits pour autre chose)
Q : en tant que programmeurs C++, nous voulons utiliser C++. Plusieurs trucs ouvrent la porte à des optimisations amusantes, ce qui entraîne de la résistance chez les gens qui aiment C comme s'il s'agissait d'un assembleur avec une syntaxe plus jolie.
Andrew Sloss : pour un programmeur C, cette proximité du langage avec l'assembleur est une priorité très importante.
(j'ai manqué quelques trucs car j'échangeais avec mon directeur de thèse; Odin Holmes relate un cas amusant où une optimisation par inlining a révélé un bogue matériel autrefois caché par la latence d'un return)
Q : pour bien réaliser une migration incrémentale d'un Build System, existe-t-il de saines pratiques?
Dan Saks : je pense que tu peux mêler C et C++ dans la mesure où main() est en C++. C++ peut accommoder le linkage C, l'inverse n'est pas vrai. Tu veux aussi un éditeur de liens commun pour tous les modules objets.
Q : j'entends que les programmeurs de systèmes embarqués sont conservateurs, et je constate que beaucoup de gens, systèmes embarqués ou autres, craignent les exceptions.
John McFarlane : vous faites probablement référence aux exceptions statiques, qui sont en stade préliminaire et ne visent pas C++ 20. Il reste à voir la résistance de WG14. Pour le moment, ça se passe bien, et le regard de WG21 est plutôt favorable. C'est un gros changement, alors faudra voir quel chemin nous suivrons... (Ben Saks pense qu'on parle d'un horizon de dix ans). Les contrats sont aussi un ajout intéressant pour la communauté des systèmes embarqués.
Brett Searles : et la Freestanding Implementation?
Ben Saks : je pense qu'on vise plus C++ 23 pour ça.
Andrew Sloss : et pour le multithreading dans les systèmes embarqués?
Odin Holmes : j'ai beaucoup d'espoirs envers les coroutines, que j'espère pour C++ 20.
John McFarlane : un bon truc est de réduire les états intermédiaires et de tirer profit de constexpr... qui permettra maintenant l'allocation dynamique de mémoire à la compilation, en ROM.
Ben Saks : les hardware_constructive_interference / hardware_destructive_interference sont trop peu connus, et sont directement utiles pour ce type de programmation.
Andrew Sloss : considérant les problèmes pris en charge par les systèmes High-End (apprentissage automatique et autres), les accélérateurs vont finir par venir rejoindre le monde des systèmes embarqués (plusieurs gens dans la salle semblent déjà se trouver dans cette situation)
Brett Searles : il y a aussi les MPU qui arrivent sur le marché (Andrew Sloss : et les TPU, qui viennent plus de Google)
On ferme vers 21 h 45. Les gens sont fatigués aujourd'hui.
Je profite du moment pour échanger avec Dan Saks, avec qui j'ai passé un moment très agréable dans un aéroport l'an dernier. C'est un individu d'une grande sagesse, et nous aurons la chance de poursuivre nos discussions demain durant la rencontre du SG14 car il se joindra à nous avec son fils
La première vidéo de la semaine a été publiée sur YouTube ce matin, et il s'agit (c'est normal) du keynote de Bjarne Stroustup. À mon avis, c'était une bonne présentation.
Aujourd'hui, après la douche, j'ai passé en revue les soumissions réussies pour mon puzzle, question de m'assurer qu'il n'y avait pas eu de triche, et il se trouve que les soumissions tirées étaient conformes. Ça m'a permis de constater que les gens n'ont pas encore compris comment tirer profit au maximum de std::variant, alors nous avons encore de l'enseignement à faire. Ce type, bien compris, est un game changer, et les gens en sous-estiment la portée.
Aujourd'hui, journée simple et compliquée à la fois : nous tenons la rencontre annuelle de SG14 conjointe avec CppCon. Nous aurons donc une rencontre ISO formelle pour toute la journée, avec un pause pour le keynote de Kate Gregory vers 10 h 30. Je serai probablement secrétaire de la rencontre, si le passé est garant de l'avenir, alors il se peut que les notes de voyage soient un peu différentes aujourd'hui et qu'elles arrivent en fin de journée.
La salle est presque pleine et Michael Wong est arrivé hier soir, ce qui lui permet d'animer la rencontre (c'est chouette; d'autres auraient pu le faire, dont John McFarlane et moi-même, mais Michael Wong est bon dans ce rôle).
Les règles ISO m'empêchent de donner le détail des travaux et des échanges de ce matin, mais une fois le volet administratif réglé (présentations, agenda, planification de la journée pour respecter les contraintes horaires des présentateurs) nous avons parlé de Trivially Relocatable (Arthur O'Dwyer). C'est un truc hyper intéressant, mais qu'il faudra polir un peu. On approche d'une autre méga optimisation en C++ avec cela.
On se déplace ensuite vers le Meidenbauer (tout près) pour le keynote de Kate Gregory, qui sera certainement excellente comme toujours. Je blague un peu avec Herb Sutter au passage qui semble d'excellente humeur.
Pour la vidéo, voir https://www.youtube.com/watch?v=n0Ak6xtVXno
Pour les diapositives, voir ceci
Jon Kalb annonce les gagnants du puzzle (mon petit puzzle). J'espère qu'ils se sont bien amusés!
Jon Kalb passe les messages d'usage (sur l'importance de récupérer son sac de joujoux, son chandail, de répondre aux sondages, ce genre de truc). Un rappel de l'importance de repecter le code de conduite est fait.
Quelqu'un dont le nom m'échappe présente Kate Gregory. Cette présentatrice a bénéficié d'une bourse de #includecpp pour venir ici.
Kate Gregory : je veux expliquer ce que je veux dire par « simple ».
Kate Gregory : quand on enseigne, on commence par quelque chose de simple. On laisse des détails de côté. On omet le traitement d'erreurs. On n'explique pas que % ne s'applique pas sur des string. On suppose que les entrées sont correctes, pas corrompues. On montre comment parcourir un conteneur dans une direction, pas nécessairement l'autre. Ce n'est pas la simplicité dont je veux parler aujourd'hui.
Kate Gregory : on simplifie pour aider les gens à se concentrer sur le message. Sur une chose à la fois. The medium is the message. On fait des exemples qui entrent sur une diapositive avec une police de caractères de grande taille. On évite de devoir alourdir la charge cognitive inutilement. On fait des exemples artificiels et sans contexte.
Kate Gregory : les gens qui vivent ces formations retournent dans la « vraie vie », et celle-ci est plus complexe. Les développeurs internalisent des trucs, et rejettent la simplicité. On montre à quel point on est bons... On fait des trucs fragiles. « Si c'est dur à écrire, faut que ce soit dur à lire ». C'est de cette simplicité que je veux parler ici. Les gens associent C++ et complexité plus qu'ils associent C++ et des mécanismes comme auto ou noexcept.
Kate Gregory : je veux traiter des mots expressive, readable, understandable, unsurprising, transparent, self-explanatory, reassuring, pleasant. Le code qui a besoin d'un commentaire car son exécution ne ressemble pas à son texte n'est pas vraiment simple. Il faut que programmer soit agréable.
Kate Gregory : plus simple signifie-t-il meilleur? Je suis d'avis que oui, bien que cette position semble subjective. Mieux? Meilleur? Meilleur que quoi? Parce que tu peux l'écrire plus rapidement, qu'il contient moins de bogues...
Kate Gregory : est-on plus rapides quand on écrit un programme simple? Définitivement pas. C'est difficile. Il faut poser un regard neuf, développer de meilleures habitudes. Il fau revisiter, refactoriser.
Kate Gregory : le code simple est-il plus correct? Oui, habituellement. Par exemple, RAII permet d'écrire moins de code... et réduit les risques d'en oublier. Plus simple, plus correct. La simplicité réduit les risques d'incohérence : une fonction plutôt que deux; un templates plutôt que dix fonctions... Déplacer la complexité vers des abstractions tend aussi à réduire les bogues. En plus, utiliser du code de bibliothèque, par exemple les algorithmes, simplifie nos vies car ce code a été testé, que les cas limites ont été identifiés.
Kate Gregory : le code simple est-il plus rapide? Elle compare for(auto p : people) et for(auto &p : people). La version la plus simple n'est pas nécessairement la plus rapide; il faut savoir des choses sur le langage pour en tirer profit. Si un choix existe entre vitesse et simplicité, préférez la vitesse... mais c'est un gros si. Nos compilateurs sont fabuleux, nos optimiseurs aussi. Si vous ne mesurez pas, c'est pratiquement certain qu'ils seront meilleurs que vous. Le code de la bibliothèque rapide est presque assurément plus rapide que le vôtre, entre autres car ces gens savent comment le reste est fait.
Kate Gregory : la simplicité est un cadeau qu'on se fait. Plus facile à comprendre, à déboguer. Souvent plus correct. Ne transformez pas C++ en un langage Write-Only comme certains qualifient Perl ou APL. Le code sans surprises est plus facile à entretenir. Le code expressif est plus agréable. Le code des autres est différent, mais il peut être beau!
Kate Gregory : atteindre une vraie simplicité est difficile. Il faut savoir beaucoup pour l'atteindre : le langage, les outils, les idiomes. Si vous ne connaissez pas any_of(), vous risquez d'écrire la fonction pour rien. Ce n'est pas la même chose que « omis pour fins de simplicité ».
Kate Gregory : y a-t-il des règles pour atteindre le code simple?
Bien choisir les noms est important. Souvent, les noms se cachent dans les commentaires. Souvent, les problèmes sont résolus par un algorithme. Les fonctions portent des noms. Remplacer des nombres par des énumération leur donne un nom. Les constantes symboliques donnent des noms. Les variables bien nommées aussi : un bon nom économise une indirection dans la lecture. Les outils peuvent aider. Donner des noms transforme un programme en un récit.
Écrire des fonctions courtes, pas seulement pour la lisibilité. Une fonction courte peut porter un nom significatif, un nom clair. Si on ne peut la nommer, ce n'est pas une fonction, c'est une fédération de fonctions. Les fonction « émotionnellement courtes » comme celles dans <algorithm> semblent vraiment courtes; elles deviennent du vocabulaire. Les gens les connaissent. Elles n'ont plus à être expliquées.
Kate Gregory montre une longue fonction pour analyser des paramètres à la ligne de commande, façon C et façon C++. Certains critiquent la vitesse, mais c'est fait une fois, au début du programme.
Kate Gregory : c'est un enjeu d'abstraction. Pensez aussi à la signature des fonctions. Évitez les longues listes de paramètres. Ne passez pas sept booléens à une fonction, passez un objet qui représente un groupe d'options. Ne passez pas quatre entiers, passez deux points ou un rectangle. Si une fonction accepte dix paramètres, c'est peut-être que trois fonctions plus petites s'y cachent? Peut-être que la fonction devrait être une méthode et dépendre d'un ou plusieurs attribut?
Kate Gregory : réduisez les niveaux d'imbrication dans les alternatives imbriquées. Return early.
Kate Gregory : const all the things. C'est plus qu'être const-correct. On veut savoir ce qui varie dans un calcul, et clarifier ce qui est stable. Mettez const partout, pour cibler ce qui ne compile plus et circonscrire ce qui demande une attention particulière. Ceci constitue une bonne raison pour éviter les paramètres sortants le plus possible, surtout maintenant qu'on peut retourner un tuple ou un struct.
Kate Gregory : tenez-vous à jour pour ce qui est des changements dans le standard, et informez vos pairs. Il faut être à jour. J'ai suggéré aux gens l'an passé d'éviter const_cast et de préférer mutable... plusieurs ne savaient pas que ça existe! Le mot clé a plus de 25 ans! Utilisez les nouvelles boucles for quand les algorithmes ne conviennent pas. Apprenez à apprécier =delete. Les NSDMI peuvent simplifier votre vie. Utilisez la bibliothèque standard : variant, optional, les algorithmes...
Kate Gregory : programmer est une activité sociale. La communication y est acte de survie. Le code que vous laissez derrière vous parle en votre nom.
Kate Gregory : The Pit of Success est un endroit où on veut que nos gens tombent. En particulier, ceci découle de choisir les bonnes valeurs et les bons comportements par défaut. Laisser des incohérences derrière soi cause des embûches inutiles. Nettoyer les ressources dans un destructeur évite les problèmes de fuites. Soyez const-corrects du début à la fin.
Kate Gregory y va d'une analogie avec les clôtures. On veut éviter les chutes accidentelles avec l'encapsulation, pas empêcher les programmeuses et les programmeurs de s'exprimer. Elle recommande de ne pas être un Architecture Astronaut qui fait des diagrammes UML qui ne veulent pas dire grand-chose. Elle recommande aussi de ne pas sur-généraliser inutilement (c'est bon quand on en a besoin, évidemment). La flexibilité demande de l'entretien, à vie. On l'implémente quand il y a un besoin, pas par défaut.
Kate Gregory : il y a un paradoxe, cependant. L'abstraction aide à la simplicité, mais l'abstraction inutile nuit. Les choses que nous faisons pour simplifier le code peuvent le complexifier. Il n'y a pas de règles simples pour écrire du code simple. Ce n'est pas un problème de C++, ou du développement logiciel, c'est un problème de l'univers entier. Apprendre à quelqu'un à conduire implique plusieurs décisions qui semblent simples. Devenir un parent ou un grand-parent aussi. En C++ :
Ensuite, il faut mettre en pratique des pratiques simples, utiliser son jugement. Encapsuler. Créer des relations. Choisir le bon algorithme. Le bon conteneur. Ne pas réécrire un parser JSON s'il en existe déjà un bon. Utiliser des trucs que les gens vont comprendre (ça peut être bon, évidemment, de montrer de nouveaux trucs aussi), pour réduire les surprises. Utiliser des idiomes familiers. Sans aller à l'excès.
Kate Gregory : la simplicité vit dans un contexte plus vaste et implique du temps. Insérer un chiffre magique semble être une économie à court terme, et devient rapidement un coût plutôt qu'une économie. Idem pour les variables globales.
Kate Gregory : la chose la plus difficile est de prendre les claques quand les gens pensent que parce que la solution semble élégante, les gens sont d'avis que le problème était simple. La simplicité peut obscurcir l'effort qui a mené à la solution. Est-ce « simple brillant » ou « simple paresseux »? Le code que vous laissez derrière vous est un message.
Kate Gregory : il faut apprendre, lire, faire attention, tester, communiquer
(j'ai manqué les premières questions)
Q : introduire des pratiques simplificatrices dans une entreprise est complexe
Kate Gregory : c'est un travail de longue haleine
Q : dans mon entreprise, j'essaie de véhiculer des pratiques semblables. Je suis inspiré de Clean Code par Robert C. Martin. Je ne suis pas un informaticien de formation, et je sens de la résistance envers l'idée de choisir de bons noms. Que peut-on faire?
Kate Gregory : les gens ont peur de perdre leur emploi. Quand on est bons, le code est propre, l'emploi est en sécurité. Les gens pertinents et généreux n'ont rien à craindre
Q : les problèmes rencontrés dans un milieu académique sont souvent trop simples pour prendre conscience de l'intérêt de l'abstraction.
Kate Gregory : on est effectivement pris avec des exemples plus humbles dans un contexte académique. Le problème est plus vaste que ce que je peux traiter ici.
C'était une bonne présentation, je compte la recommander à mes collègues. Le contenu est plus général que le seul langage C++; c'est intelligent et bien amené. Un truc qui est revenu ce matin et qu'il faudra aborder là où j'enseigne est la question du Early Return, du moins à partir de la session 2 ou 3. Nos pratiques traditionnelles sont malsaines dans des programmes contemporains.
Nous n'avons que très peu de temps pour dîner, alors je fais la file chez Subway's pour accrocher un sandwich au thon et je retourner m'installer dans la salle de réunion. Je ne suis pas seul. Pour une raison que personne ne semble connaître, le Wi-Fi ne fonctionne pas là où nous sommes; je prends les notes pour la rencontre sans pouvoir les mettre à jour sur le Wiki... C'est une source de stress.
Les travaux reprennent à 14 h (la logistique du dîner était trop complexe; nous sommes vraiment très nombreux). Le Wi-Fi ne fonctionne toujours pas.
Les travaux de ce tronçon sont centrés sur deux dossiers : quelques votes en lien avec la propositon sur Trivially Relocatable par Arthur O'Dwyer, puis une présentation détaillée de retain_ptr<T> par Isabella Muerte.
Courte pause pour manger une grignotine, et on recommence.
La dernière portion de la journée nous a permis de discuter de la proposition de géométrie et d'algèbre linéaire ave Guy Davidson, puis du Freestanding Implementation avec Ben Saks. Une grosse fin de journée.
Après la rencontre, je n'avais toujours pas de Wi-Fi et pour faire exprès, la coupure s'était faite alors que j'essayais de pousser le détail de la rencontre à distance, alors je devais être ultra prudent de ne pas perdre la fin de notre journée.
Je suis parti vers le souper des planificateurs (Planners' Dinner) au https://www.lincolnsfh.com/ avec Ólafur Waage, Billy Baker, Hubert Tong et Matt Calabrese. J'ai profité du Wi-Fi là-bas pour terminer la sauvegarde des travaux de la journée, puis j'ai pris une pizza (pas vilaine : piment, kale poulet, fromage) en bavardant avec Billy Baker, Bob Steagall et Jesse Williamson, un très gentil bénévole avec qui je parle plusieurs fois à chaque visite et dont le nom m'échappe souvent (je suis gêné). Je suis ensuite retourné m'installer pour répondre à mes étudiant(e)s qui ont un examen demain et vivent du stress. J'en ai profité pour bavarder avec le toujours sympathique Kévin Boissonneault et son tout aussi sympathique collègue dont le nom m'échappe (je suis gêné au carré)
Le keynote de Mark Elendt est déjà en ligne. Wow!
On aura plusieurs Lightning Talks ce soir (plus d'une douzaine, cinq minutes maximum chacun). Michael Caisse anime ça de main de maître.
Arvid Norberg – Test coverage parle... de test coverage, donc de ce qui doit être conservé ou retiré d'une gamme de tests. Il distingue les tests qui comptent, qu'on veut faire, et les collatéraux. Il s'en sort en trois minutes.
C. J. Johnson – constexpr and operator overloading and everything is terrible parle d'une implémentation d'optional avec un union, où un comique a surchargé l'opérateur & et où il s'avère que constexpr est appliqué à operator-> ce qui empêche d'utiliser addressof en C++ 11. Il s'en sort presque en remplaçant ou T par un T[1] et en appliquant + dessus pour avoir un pointer decay. Trois minutes trente
Diego rodriguez-Losada – Why not conan? qui donne des raisons (humoristiques!) de ne pas utiliser son produit. Il compte proposer quelque chose pour SG15 à San Diego. Drôle, bien fait, quatre minutes
Tony Wasserka – Curly Function Call Syntax parle de l'initialisation avec { et }. C'est tellement beau... qu'il veut en utiliser encore plus! Il écrit des constructeurs appelés avec des accolades qui appellent des fonctions. Il parle du côté unsequenced des paramètres aux fonctions et montre que les accolades imposent l'ordre. Il se fait couper à cinq minutes
Tsu-Wei Huang (je pense) – Fast Parallel Programming Using Modern C++ parle de Taskflow. Son code de base (hard-codé) n'est pas très bon, cependant. Taskflow est charmant cependant. On décrit les dépendances et ça gère les enchaînements. Cinq minutes pile
Jon Kalb – This is Why We can't Have Nice Things parle de east const / west const (son combat ces temps-ci). Cinq minutes
Boris Stanimirov – The Bad Big Wolf Meets Riding Hood Little Red parle de linguistique, et est une critique du combat de Jon Kalb et une démonstration que la forme qu'il met de l'avant est de l'anglais suspect. C'est très réussi et on se bidonne beaucoup. Il se fait couper à cinq minutes
Peter Sommerlad – rof_egnar reversed adapter parle d'un adaptateur pour inverser la traversée d'une séquence avec une répétitive for sur un intervalle. J'ai déjà fait un truc du genre pour dépanner Ólafur Waage dans le passé. Il suggère de supprimer les méthodes && sur begin() et end(). Il se fait couper à cinq minutes
Jens Weller – Generating UI with C++, boost & Qt parle d'une expérimentation de son cru. Ça implique Verdigris pour faire des mocks. Boost::Fusion. Boost::mp11. Il génère des noms à partir de struct. Cinq minutes
Kris Jusiak – Boost.DI Inject All The Things parle de l'injection de dépendances comme le Don't Call Us, We'll Call You de la programmation. Il fait des fabriques en réordonnançant dynamiquement les paramètres. Cinq minutes
Staffan Tjernstrom – Almost Always Avoid auto parle de auto comme d'une plaie. Il dit que c'est bon, mais qu'on abuse... Il relate une histoire de fonction auto à plusieurs niveaux de profondeur. Cinq minutes
Nimrod Sapir – The Perfect Job Interview (maybe) parle de recrutement, et d'entrevues techniques. Cinq minutes
Jonathan Keinan – Cache Warming (Wamr Up The Code) parle de trucs pour garder la cache prête à traiter du code critique utilisé moins souvent (p. ex. : appeler la fonction critique souvent, mais avec un paramètre qui permet d'en ignorer les calculs). Techniques sympa pour moi. Se remplace par [[likely]]. Cinq minutes
Chuck Wilcox – Zero-Overhead Compiler Pessimization parle de comment réaliser de bons benchmarks sans que l'optimiseur ne nous joue des tours. Google Benchmark, Celero et Facebook Folly ont des outils pour ça. Cinq minutes
Ryan Ruth – std::basic_string for more than just text parle d'écrire du code que personne ne comprendra. Il remplace vector<bool> par... basic_string<bool>! Il utilise SSO pour une basic_string<point> avec point fait de deux int8_t. Cinq minutes
Matthew von Arx – Set it and Forget it! parle de divers outils pour se simplifier la vie. Il est drôle. Quatre minutes trente
Walter E. Brown – Communicating via Diagnostics: Observations and Tips for Authors parle de distinguer le code correct et le code qui n'a pas encore échoué, de même que de l'importance de soumettre de bons diagnostics. C'est divertissant et intelligent. Cinq minutes
On finit vers 22 h 20. Grosse journée, grosse soirée. J'ai travaillé un peu à l'hôtel mais je suis rapidement tombé d'épuisement...
... et je me suis levé un peu tard ce matin (en fait, je me suis levé à temps, puis rendormi, puis réveillé, puis rendormi, puis...) mais heureusement, mon amoureuse Za m'a réveillé par Skype pour me faire participer à distance à une très chouette activité de préparation de compote de pommes à la maternelle. J'ai pu voir Ludo découper des formes dans du papier, les coller, porter un chapeau très élégant, faire un peu de science (vérifier des hypothèses quant à la flottaison ou pas de pommes et de morceaux de pommes), se mesurer (il mesure huit pommes, apparemment), et interagir avec ses amis. Un immense merci mon amour!
J'ai ensuite pris ma douche et je me suis préparé pour la journée. J'essaie d'arriver vers 7 h 30 heure locale car je suis supposé aider Stoyan Nikolov qui a décidé de participer à notre programme de mentorat ici, et il présente à 9 h. J'aurais aimé le voir plus tôt cette semaine, mais je pense qu'il était un peu gêné alors je l'ai relancé hier soir. Au pire, j'assisterai à sa présentation et on fera un post mortem ensuite.
Jon Kalb et Phil Nash tiennent un CppChat live ce matin ici avec Nicolai Josuttis, et font de même demain matin avec Herb Sutter. Je vais essayer d'aller assister dans les deux cas. C'est à 8 h, avant le début des activités formelles. J'ai d'ailleurs marché avec Jon Kalb ce matin (on était dans le même ascenseur) et il semble passer une bonne semaine dans l'ensemble, ce qui est bien sûr une bonne nouvelle.
Pour la vidéo, voir ceci
La rencontre commence à temps. Ça a été annoncé un peu tard (hier soir à l'heure du souper), mais la salle demeure quand même à moitié pleine.
Jon Kalb et Phil Nash accueillent Nicolai Josuttis. Une fois les échanges cordiaux de base faits, les échanges portent au début sur la complexité croissante du langage : il s'améliore, mais il est plein de pièges. Nicolai Josuttis parle en détail de l'initialisation, qui l'occupe beaucoup ces temps-ci. Il est d'avis qu'il y a trop de règles. Nicolai Josuttis a contribué au premier standard de C++, et dit apprendre encore aujourd'hui. Il parle des Hidden Friends où une définition d'une fonction amie interne à la classe a de subtiles différences avec la même définition hors de la classe, car certaines conversions implicites sont différentes dans les deux cas. C'est... obscur. Mieux vaut implémenter les fonctions amies dans la classe pour cette raison.
Jon Kalb demande comment le cours que Nicolai Josuttis a donné s'est passé, comment étaient les participant(e)s. Nicolai Josuttis dit qu'il a eu moins besoin qu'à l'habitude de faire des introductions en début de formation, ce qui lui a permis d'aller un peu plus loin. Phil Nash dit que Nicolai Josuttis donnera aussi une formation à C++ on Sea, qu'il organise. Il y a plusieurs autres gros noms là-bas aussi. Nicolai Josuttis dit avoir discuté de constexpr! avec Jason Turner; Nicolai Josuttis blague que if constexpr devrait être renommé if constexpr! pour fins de cohérence. Phil Nash blague que constexpr? devrait exister pour les cas où on n'est pas sûrs. Le contexte de constexpr! et de if constexpr est ... subtil.
Nicolai Josuttis parle ensuite des TS. Ça a du bon, mais les gens ne portent pas assez attention et ils est facile d'adopter des idées imparfaites dans un IS par accident. Il parle des guillemets dans la représentation sous forme de texte d'un répertoire avc <filesystem>.
Nicolai Josuttis revient sur l'initialisation. Il pense que le fait que le progrès est poussé par des expert(e)s est un problème, et que l'importance d'avoir des règles triviales pour les opérations triviales est sous-estimée. Il n'est pas contre les spécialisations, mais pense que ça nous prend des comportements simples par défaut qui soient plus faciles à apprendre. Le fait que std::array soit un agrégat a des conséquences (entre autres, initialiser un array<complex>{1,2} et initialiser un vector<complex>{1,2} fait quelque chose de tout à fait différent). Jon Kalb pense qu'on aurait pu détecter ceci avec une TS; maintenant il est trop tard.
Nicolai Josuttis pense qu'on devrait avoir plus de Tony Tables (avant / après). La métaprogrammation à l'aide de templates le surprend encore 25 ans après l'arrivée des templates dans le langage. Il pense aussi qu'on trop de cas où la même syntaxe porte deux sémantiques (le && pour rvalue references et pour forwarding references; les () autour des valeurs retournées qui brisent le comportement de decltype; etc.)
Jon Kalb reprend une idée de Bjarne Stroustrup qui rappelle souvent qu'une syntaxe « bruyante » pour les nouveaux mécanismes est une fausse bonne idée : les nouveaux mécanismes ne restent pas nouveaux longtemps, après tout, et la syntaxe reste par la suite.
Une discussion s'ensuit sur la POO classique qui a mal vieilli, et sur les mécanismes plus contemporains et plus efficaces. La POO classique (encapsulation – mal comprise – héritage, polymorphisme) a encore ses usages, mais il y a plus à enseigner pour tirer le maximum de nos programmes et l'apprentissage se complique. Les nouveaux types qui ont des sémantiques de référence comme string_view, span et existent pour la vitesse représentent une complexité ajoutée pour comprendre la durée de vie des objets.
Jon Kalb dit que les guides de style sont moins utiles que les compilateurs et fait l'éloge de godbolt.org. Nicolai Josuttis pense que le langage est trop complexe pour éviter les recettes. Il y avait beaucoup moins de cas particuliers en 1998. Nicolai Josuttis dit que abseil.io et lui recommandent exactement les pratiques opposées en ce qui a trait aux initialisations, ce qui est un cauchemar. Nicolai Josuttis pense aussi que les véritables Expert Features sont moins nombreux qu'on pense : les usagers mettent les mains sur tout à un moment donné.
Phil Nash demande comment avance la rédaction du nouveau volume sur la bibliothèque standard. Nicolai Josuttis dit que ça avance bien. Il aimerait que CWG se préoccupe plus des conséquences des décisions prises dans le Core Language sur LWG. Phil Nash se demande si les nouveaux types vocabulaires comme optional et variant devraient migrer de la bibliothèque vers le langage; Nicolai Josuttis n'est pas sûr que ce soit une bonne idée mais trouve la question intéressante. Il se dit content de ne pas avoir à trancher. Nicolai Josuttis se dit d'avis que std::byte est plus délicat : cette chose devrait peut-être faire partie du Core Language.
On arrête vers 8 h 45.
Je descends au sous-sol pour saluer Stoyan Nikolov, qui a hérité d'une très grande salle ce matin.
Pour la vidéo, voir https://www.youtube.com/watch?v=yy8jQgmhbAU
Pour les diapositives, voir ceci
Étant donné que Stoyan Nikolov souhaite une rétroaction post-présentation, je ne prendrai pas le même type de notes qu'à l'habitude et je travaillerai dans une optique de mentorat / encadrement. Ce qui suivra sera un résumé de la présentation seulement.
C'était une discussion intéressante du Data-Oriented Design, un sujet pertinent et qui recoupe beaucoup les préoccupations de mes étudiant(e)s du monde du jeu vidéo de même que celles de mes collègues de SG14. J'ai beaucoup de réserves quant à la vision de la POO qui y est véhiculée, qui ressemble à ce qu'on faisait il y a vingt ans (et qui a mal vieilli) plus qu'à l'approche plus pragmatique qui est véhiculée aujourd'hui, toutefois. Je ne suis pas le seul à l'avoir remarqué, et ça se sentait dans les questions.
Il y a toutefois beaucoup de bon à dire sur le contenu de cette présentation. J'ai pris plusieurs notes dont je vais discuter avec Stoyan Nikolov quand il sera prêt.
Je vais me chercher un café et un yogourt.
Pour la vidéo, voir https://www.youtube.com/watch?v=80BZxujhY38
Pour les diapositives, voir ceci
J'ai des ennuis avec mon ordinateur qui me coûtent la pause...
Herb Sutter parle d'ajouter des mécanismes pour simplifier le langag, et de retirer des mécanismes pour le simplifier.
Pour l'ajout : gain constant, nom fixe (range-for, lambda); gain linéairem abstraction par l'usager, noms avec sens (concepts); comportement nommé, gain exponentiel (variable / fonction / classe... module)? Les noms ont du pouvoir, et l'encapsulation est un gain combinatoire et composable.
La partie exposée et la partie interne comptent à chaque fois (interface / implémentation; signature / définition). Les modules sont une nouvelle frontière d'encapsulation
Herb Sutter veut parler de durée de vie (simplifier en enlevant des cas limites) et de métaclasses (favoriser l'écriture de classes, remplacer des mécanismes douloureux, aider à nommer les choses)
Herb Sutter présente un comparatif avant / après de code de 1998 et de code contemporain. C'est bon d'avoir un rappel de l'immense amélioration que nous sommes parvenus à réaliser. Les deux demeurent du C++, mais sont très différents au regard
Les principes demeurent l'abstraction à coût nul (You Don't Pay For What You Don't Use), déterminisme et contrôle (sur le temps et l'espace; Leave No Room For A Lower-Level Language); compatbilité à l'édition des liens (avec le code du passé). Le comportement statique (constantes, mécanismes, typage) a beaucoup aidé à maintenir ces forces. Herb Sutter indique que les efforts pour supprimer typeid vont débuter dès que les métaclasses et la réflexivité seront dans le langage (remplacer dynamique par statique)
Ce qui n'est pas au coeur de C++ est la syntaxe (elle change avec le temps), la lourdeur, les défauts mal choisis, et les contours périlleux. Plusieurs de ces aspects sont des choix des usagers, pas des obligations du langage (les meilleurs outils sont là, mais certains ne les utilisent pas).
Herb Sutter dit qu'amener un nouveau mécanisme devrait nous amener à se demander en quoi ce mécanisme aide à exprimer les intentions des programmeuses et des programmeurs. Comment cela rend-il le code plus simple à lire? En quoi cela réduit-il les pièges? En quoi ceci réduit-il les cas où nous payons pour ce dont nous n'avons pas vraiment besoin (RTTI, exceptions)? En quoi ceci aide-t-il à éliminer des mécanismes dont nous préférerions nous passer (macros)?
Herb Sutter mentionne le cas de using, qui fait beaucoup plus (et beaucoup mieux!) que typedef
Herb Sutter présente une progression dans ses travaux pour suivre la durée de vie des objets qui expirent. Il parle d'un focus plus circonscrit (plutôt que de chercher à tout valider, il vise un succès à court terme pour dépister les cas les plus communs, pour que ça puisse faire partie de la validation normale faite par un compilateur, même par Intellisense dans Visual Studio). Semble que clang s'en sorte avec un overhead de 5% en temps de compilation, mais sans avoir fait la moindre optimisation encore. Si les outils sont meilleurs, l'enseignement sera plus simple.
Herb Sutter explique ensuite l'approche plus en détail; je vous invite à regarder la présentation pour ça, c'est intéressant. Il introduit une notation de suivi de la durée de vie des référés pour dépister les référents qui deviennent invalides. Il trace un triplet dangling -> dereference -> undefined behavior
Herb Sutter invite les implémenteurs de son mécanisme chez Clang sur la scène, et fait de la publicité pour leur présentation. Ils utilisent godbolt avec des exemples empruntés à Jason Turner. Herb Sutter fait un point important : c'est correct d'avoir une dangling reference ou un dangling pointer, on le fait à chaque fois qu'on itère sur une séquence avec des pointeurs; ce qui est incorrect est de le déréférencer.
Herb Sutter indique que ceci simplifie le code C++ et améliore la lisibilité. Il passe ensuite aux métaclasses. Le prototype de 2017 a été amélioré et raffiné. Une ovation est donnée à Matt Godbolt au passage pour tout ce qu'il a fait pour la communauté.
Herb Sutter présente les métaclasses comme une stratégie de nommage pour des familles non-intrusives de classes. On voit une évolution de la syntaxe proposée (je vous invite à regarder la présentation pour les détails). Il fait des objets gardés (qui sont lockable) et des objets actifs (sorte d'acteurs). Ses objets actifs sont comme mes autonomes, mais avec une file de messages (les messages sont des function<void()>; le constructeur lance un thread qui consomme de la file de manière bloquante et attend que done devienne true; quand un message entre, done devient true; le destructeur attend la fin du thread). Avec sa technique, il est important que l'instance de Active soit le dernier dans la classe qui le contient. Il a un chic pipeline fait de variables locales (l'ordre est important). L'équivalent Java est... déplaisant, et fragile. Un impact intéressant est qu'il arrive à remplacer du TLS par une variable locale (moins lourd). Enfin, il écrit des propriétés. Dans les trois cas, ce sont des mécanismes intéressants, mais pas nécessairement dignes de standardisation. Ses propriétés sont plus concises que celles de C#, surtout quand elles sont non-triviales.
Herb Sutter rappelle qu'un des objectifs de la démarche est d'éliminer une partie des dialectes comme C++/CLI, C++/CX ou MIDL. Le langage devient plus extensible.
Il finit en montrant une métaclasse pointer, car tout ce qui était démontré aujourd'hui est dans godbolt, et il joint les deux mécanismes d'aujourd'hui pour remplacer les pointeurs bruts... avec gestion de durée de vie inclus! C'est pas mal charmant.
Herb Sutter finit en exhortant les gens à continuer à améliorer le langage en le simplifiant à coût nul.
Q : comment déboguer et tester une métaclasse?
Herb Sutter : j'en ai parlé l'an passé, mais je peux générer des informations à la compilation.
Q : dans la nouvelle syntaxe des métaclasses, comment contrôler ce qui est généré dans / hors de la classe?
Herb Sutter : pour le moment, on génère là où on est.
Q : comment cela se joint-il aux concepts?
Herb Sutter : (je manque la réponse)
Je suis allé luncher avec Stoyan Nikolov et un de ses amis (qui travaille chez Ubisoft Toronto) pour faire un retour sur sa présentation, ce qui m'a fait manquer le panel sur la sécurité logicielle, mais ça valait la peine.
Ce panel est composé de Patricia Aas, Matthew Butler,
Eva Conti, Matt Miller et
Michael Wong, mais je n'ai
pas pu y aller.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
J'ai hésité longtemps etre cette présentation et celle de Geoffrey Rohmer sur le Thread-Safety (je suis plus threading que mathématique, règle générale), mais JF Bastien m'a convaincu de venir le voir hier en me laissant entendre que je serais diverti par ses diapos. Je n'en doute pas une seconde... En attendant, je discute avec un de mes participants de la fin de semaine dernière; il semble avori apprécié.
JF Bastien : il y a plusieurs trucs à faire sur un comité comme WG21, trop pour une personne, alors je m'occupe des trucs qui m'énervent. Ici, ça a commencé sur Twitter : les entiers signés sont UB à cause de la variété d'implémentations possibles, mais les entiers signés atomiques sont implémentés avc complément à 2 (la définition est incorrecte et il y a du UB technique, mais on va le corriger)
JF Bastien : un truc qui m'énerve est un test de débordement du genre template<class Int>bool overflows(Int gauche, Int droite){ return(gauche+droite)<gauche;} qui ne fonctionne pas car c'est UB et le code généré est incorrect
JF Bastien : la version correcte est de convertir aux non-signés équivalents... C'est pas évident
JF Bastien : vérifier le débordement du max du type n'est pas terrible (son exemple est UB mais le compilateur n'en profite pas). Il fairt une manoeuvre avec une atomique qui est complément à 2, mais le code généré est merdique. Il utilise ensuite des bitfields (piache), pour qu'un débordement donne du comportement implementation-defined... ce qui peut être UB si tel est le souhait des concepteurs.
JF Bastien : tester les débordements en haut et en bas donne du très mauvais code.
JF Bastien : il y a des intrinsèques, cela dit. Le code généré est excellent, ce qui veut dire que le matériel le fait bien... mais que le langage combat mon intention.
JF Bastien présente quelques cas de débordements célèbres. Voir les diapos pour des détails. Il a un bogue de Pacman (niveau 256), un bogue de Donkey Kong (niveau 26) et un bogue de Civilization (Gandhi devient échant à un certain point), er Dream Devourer dans Chrono où on peut tuer le boss en le guérissant, causant un débordement qui lui donne une vie négative. Il montre ensuite un bogue de Bitcoin. Moins comique, un débordement qui pourrait faire briser les protections des moteurs à tous les huit mois (donc, faut les redémarrer à l'occasion). Le cas du Ariane 5, qui a explosé dû à un débordement... dans du code qui ne devait même pas être exécuté.
JF Bastien parle du programmeur en colère, et fait des blagues sur Linus Torvalds. Il sort une citation indiquant que le texte du standard est sans intérêt car la machine fera ce qu'on lui demande. Il applique les recommandations de Linus Torvalds et regarde ses recommandations. Le code généré est bon, mais aucun des bogues célèbres listés n'aurait été corrigé par ces manoeuvres.
JF Bastien explique ensuite sa recherche pour voir ce qui peut être fait. Il rappelle que même la valeur absolue peut déborder. Il fait un retour sur la représentation des entiers.
JF Bastien : C++ s'inspire de C, qui est plus restrictif, mais a des « valeurs extraordinaires ». Il est entre autres possible d'avoir plusieurs zéros entiers en C. Il cite Donald E. Knuth, et il cite Liebnitz (qui a inventé l'arithmétique binaire... en français! En fait, réinventé car les chinois et d'autres l'avaient fait avant). Pour Liebnitz, l'arithmétique binaire était une preuve de l'existence de Dieu
JF Bastien : Thomas Rodgers a fait la recherche sur les plateformes supportant d'autres formats que le complément à 2 pour ne pas en trouver... depuis les années '60, du moins pour les plateformes qui supportent C++.
JF Bastien : le comité ne veut pas définir les débordements, car on travaille pour une machine asbtraite. Ça empêche certaines optimisations. De plus, la majorité des débordements concrets sont des bogues à corriger; définir un comportement ne permet pas de détecteur / corriger des bogues. Il cite une recherche de Krister Walfridsson qui a étudié le traitement des débordements sur gcc. Automatiser les tests entraîne des coûts. C'est pas acceptable pour un compilateur. Il montre une table de Lawrence Crowl pour voir les créneaux de tests / propriétés par type d'entier pour voir quel est l'espace à définir / à occuper.
JF Bastien : pour ne pas définir l'arithmétique, je me suis occupé de définir l'entreposage.
JF Bastien : il y a des solutions : des intrinsèques, des types spécialisés, des outils de vérification, des changements au langage, ajouter des blocks checked, un débordement défini, lever une exception, saturer... introduire un unrefined behavior >rires!<
JF Bastien discute des difficultés de faire avancer un dossier comme celui-là dans un comité. Il parle du côté humain de la gestion du temps dans les circonstances. Il suggère le site coolstory.wtf qui a été fait par un artisan de Rust.
JF Bastien : la réception initiale fut que to wrap n'était pas souhaitable, de pas définir l'arithmétique. Pour le reste, cool, ça s'est bien passé, surtout sur la base de la recherche faire par Thomas Rodgers. Faut faire passer ça par CWG maintenant. Ensuite, Aaron Ballman a porté sa proposition WG14 qui a aussi aimé! La proposition est p0907
JF Bastien : le plan est de réduire le nombre de représentations possibles pour les entiers signés, puis standardiser de meilleurs entiers... pour des architectures qui n'existent pas. Il suggère d'autres pistes de simplification visées (comme les architectures à un nombre de bits par byte différent de 8). Imposer que char soit signé. Imposer IEEE754. Déprécier volatile... etc.
Q : pourrait-on tirer plus de vitesse en changeant le comportement du débordement des entiers non-signés indéfini?
JF Bastien : on ne peut pas briser le code défini qui existe déjà.
Q : qu'est-ce qui impacte le plus la programmation au quotidien dans tout ça?
JF Bastien : plusieurs petits trucs : un bool serait 0 ou 1, il n'y aurait pas de Padding Bits dedans, il n'y aurait (éventuellement) pas de Padding dans un entier, etc.
On arrête à 15 h pile. Du bon travail, mais il est pas mal bon pour ce type de présentation.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
C'est une journée où il est difficile de choisir les présentations. J'ai décidé de m'amuser et d'aller à celle d'Adi Shavit. En partie parce qu'il est sympathique, en partie parce qu'il semblait intéressé à ce que j'aille faire un tour, et en partie parce que je ne suis pas sûr que je vais apprendre quelque chose mais je risque de rire à quelques reprises.
Adi Shavit : je compte faire une visite des donjons terminologiques de C++. J'y vais en ordre lexicographique :
Adi Shavit cite Bjarne Stroustrup qui dit qu'il y a les langages compliqués et les langages que personne n'utilise.
Adi Shavit : il y a aussi :
Je vais féliciter Adi Shavit rapidement, je me prends une bouchée (il y a des mini empanadas) et je vais vers la prochaine présentation... qui est déjà commencée.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Il y a beaucoup de gens dans la salle. Je regarde les premières diapos en mangeant mes empanadas, puis je me mets à la prise de notes.
Damien Buhl commence par décrire les bases de ce qu'est WebAssembly, puis enchaîne sur la structure des modules avec ce format. Il fait un petit main() qui se limite à un return et montre le code WebAssembly généré. Les modules WebAssembly ressemblent, de manière amusante, un peu à du Lisp (c'est structuré à l'aide de parenthèses). Les seuls types sont des fonctions. La machine virtuelle est une machine à pile. On y trouve le type, les importations, les fonctions, les exportations et le data. C'est un format à la fois portable... et natif.
Damien Buhl : le modèle d'exécution est téléchargement, compilation initiale (naïve), exécution, et recompilation optimisante. Le codegen devient excellent.
Damien Buhl : le WASM runtime est natif (pas d'émulation). La pile et le tas sont contigus, et il n'y a pas de collecte d'ordures. Un schéma explique que cette absence de collecte d'ordures est une réalité même si le fureteur exécute normalement du JavaScript qui, lui, a une collecte d'ordures. Pour toucher à JavaScript, il faut passer par une API qui gère l'interaction entre les deux mondes.
Damien Buhl : pour ce qui est du multithreading, WASM supporte les pthreads. C'est implémenté, ça fonctionne. C'est toutefois basé sur SharedArrayBuffer, qui a une mauvaise réputation dû à Spectre et est souvent désactivé.
Damien Buhl : pour ce qui est du développement Web, un des enjeux est de faire interopérer C++ (typage statique) et JavaScript (typage dynamique). Les deux partagent une philosophie : ouverture, flexibilité, extensibilité. TypeScript s'ajoute au portait pour aider à l'évolution de JavaScript. Damien Buhl fait, en quelques lignes, un site Web dynamique en C++ inspiré du site de TypeScript et change le logo par programmation. C'est joli, c'est smooth, ça utilise une lambda mutable.
Damien Buhl aborde ensuite la question des services Web selon une approche ReST. Il montre un exemple JavaScript avec un Framework, qui est simple mais dangereux faute de types, et écrit plutôt quelques lignes de C++ pour faire la même chose mais de manière sécuritaire. Il utilise du C++ 17; il faut un peu comme de la POA en C++. Il montre que JavaScript est plus rapide que C++... mais qu'après un certain nombre de requêtes, la collecte d'ordures embarque et C++, étant plus stable, prend les devants
Damien Buhl utilise Boost.Hana dans WebAssembly (cool!). Ensuite, il montre qu'avec if constexpr et is_trivially_copyable_v, on peut dépasser la compétititon.
Court mais intéressant. Je descends dans l'une des grandes salles au sous-sol (Stephan T. Lavavej est un présentateur populaire!) et je parle aux plus jeunes de mon retour à la maison « demain » (je ferai le Red Eye toute la nuit durant, pendant qu'ils feront dodo). J'apprends au passage que ma belle Calypso, celle de mes enfants que je vois le moins souvent ces temps-ci (elle habite dans la ville de Québec) sera de passage à mon retour, ce qui rend le retour encore plus heureux!
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Je bavarde un peu avec Jeff Snyder, qui a écrit l'une des propositions les plus populaires pour C++ 20 (il a réussi à étendre le champ des possibles pour les types qui peuvent être utilisés dans un template; il a été fréquemment cité et remercié cette semaine!). Il pense faire une présentatiom à ce sujet l'an prochain. C'est amusant de parler avec quelqu'un ui est perpétuellement en train de résoudre un cube Rubik.
Stephan T. Lavavej est drôle. Il montre comment prononcer son nom, où sont les numéros de diapos (pour poser des questions), ce qu'est CTAD, etc. Il insiste sur le fait que c'est un Core Language Feature, qui peut être utilisé dans le code en général.
Stephan T. Lavavej commence par un tour d'horizon de la programmation avec des templates en C++ avant C++ 17. Il montre la distinction entre la déduction des paramètres des fonctions et celle des types.
Stephan T. Lavavej : so Hello World de CTAD et un pair p(1729, "taxicab") suivi de static_assert(decltype(p), pair<int,const char*>) même si "taxicab" est un char[8]. Ça fonctionne avec des parenthèses comme avec des accolades, avec direct-initialization ou copy-initialization. Il explique que la déduction passe par des Deduction Guides.
Stephan T. Lavavej montre quelques cas de verrous (shared_lock, scoped_lock – qui est variadique! – et lock_guard). Il montre ensuite comment trier en ordre décroissant un array initialisé avec des littéraux string_view (le type et la taille du array sont déduits). On peut aussi écrire greater{} au lieu de greater<>{} dû à CTAD.
Stephan T. Lavavej montre un exemple où un vecteur est créé à partir d'une list<pair<int,string>> et de rbegin(), rend(). CTAD fonctionne, et à deux niveaux!
Stephan T. Lavavej aborde des erreurs de base. Certains sont évidents (pair p{}), d'autres aussi mais différents de C# ou Java (array arr{ 1,2.5,3 }) par choix de notre part (on a les outils, mais on trouve que c'est une mauvaise idée), d'autres subtils (shared_ptr p{ new string };, ce qui m'est arrivé hier!), dû au support des tableaux et à leur décrépitude en pointeurs
Stephan T. Lavavej aborde les limites de CTAD. Ça ne fonctionne pas avec les alias sur des templates ou avec des paramètres explicites. Faut ausi des guides de déductions pour les agrégats. Aussi, c'est un tout ou rien (on ne peut pas écrire array<string> ar{ "Yo"s, "man"s } et espérer la déduction du 2).
Stephan T. Lavavej aborde la question de la déduction implicite ou pas. Par défaut, les types d'une pair triviale seraient déduits, mais pour "yo" ou aurait char[3] (faut un guide de déduction pour avoir autre chose). Aussi, constructible et déductible sont deux idées distinctes (il montre un type T,U avec un constructeur T... Ce ne serait pas déductible car il manqerait U). Il a un cas amusant acceptant un T* et recevant nullptr qui n'est pas un pointeur.
Stephan T. Lavavej : les paramètres avec type par défaut fonctionnent (heureusement pour les conteneurs avec allocateurs!)
Stephan T. Lavavej passe ensuite aux guides de déduction. Il donne un exemple d'un vector<T> avec un constructeur générique template<class It> vector(It,It);. Le Hello World des guides de déduction est template <class It> vector(It,It) -> vector(typename iterator_traits<It>::value_type);
Stephan T. Lavavej : le Perfect Forwarding empêche CTAD. Faut un guide de déduction pour template<class A, class B>struct Pair{ template <class T, class U> Pair(T&&,U&&); };... et le guide est template <class X, class Y> Pair(X,Y) -> Pair<X,Y>; ce qui est amusant. Ceci veut dire que CTAD passe avant Overload Resolution et n'affecte pas les appells de constructeurs; ça ne fait que déterminer quels constructeurs appeler.
Stephan T. Lavavej : la diapo 40 montre des techniques pour imposer des requis sur la déduction des array (pour imposer que les types des valeurs soient les mêmes).
Stephan T. Lavavej suggère de bien tester ses hypothèses (static_assert), pour éviter les surprises.
Stephan T. Lavavej : couvre des cas suspects. Il recommande de ne pas les imiter. C'est amusant. Ça touche les non-deduced contexts, avec ou sans alias.
Stephan T. Lavavej apporte des diapos boni. Il a un exemple par exemple où CTAD peut réussir mais overload resolution peut échouer par la suite. Il se peut aussi que CTAD et es constructeurs, pris ensemble, mènent à une ambiguïté.
Stephan T. Lavavej : montre quelques diapos sur <charconv> avec to_chars() et from_chars() dont il compte parler l'an prochain. Il sort des benchmarks... superbes!
Q : à la diapo 27, on voit un cas où CTAD n'aurait pas déduit le bon type. Si j'avais livré le code avec une déduction impropre, qu'aurais-je dû faire?
Stephan T. Lavavej : faudrait que l'erreur soit vraiment utile pour que les gens ne préfèrent pas ta version corrigée.
Q : est-ce que ça marche avec map?
Stephan T. Lavavej : c'est pas sa force. Avec un paquet d'accolades, c'est difficile, mais si on explicite les paires, ça fonctionne. C'est une limite de cette version du mécanisme.
Q : quelles sont les règles de l'interaction avec les espaces nommés?
Stephan T. Lavavej : je ne sais pas par coeur; je vis surtout dans std. CTAD n'est pas intrusif, alors ça devrait relativement bien se comporter.
Alisdair Meredith : préférez éviter les guides dans un .h si possible pour éviter de créer le chaos.
Arthur O'Dwyer : excellente présentation, mais je déteste toujours autant CTAD.
Stephan T. Lavavej explique que ça fonctionne bien en général, et que le rapport coûts / bénéfices est excellent.
Q : comment est-ce que ça va interopérer avec les métaclasses?
Stephan T. Lavavej : demande à Herb Sutter. J'en ai aucune idée.
C'était amusant et extrêmement instructif, comme toujours.C'est le moment d'aller au Speakers' Dinner.
Brièvement : j'étais à la table 3, avec Chandler Carruth, James McNellis, et cinq personnes qui ont payé pour manger et parler avec nous. Tout le monde était gentil, la bouffe était bonne, le vin aussi. Le repas comprenait un peu de rôti, des petites patates au four, une bonne salade (fruits séchés, fromage, mesclun, vinaigrette au champagne), du pain avec un beurre fouetté et un beurre pesto, saumon aux tomates (le saumon était bon; la sauce aussi, mais ça n'aurait pas été mon choix), des aubergines légèrement panées, des broccolini sautés, et un petit crumble dans un petit pot. Ce fut bien agréable; de manière générale, l'ambiance cette semaine était excellente.
Bryce Adelstein-Lelbach souhaite qu'on ait des Tracks thématiques l'an prochain et m'a demandé d'en prendre une en charge; je lui ai dit que ça me ferait plaisir.
Bob Steagall doit diriger le Kick-off Meeting ce soir et m'a demandé d'être secrétaire; ça ne me dérange pas, je prends des notes de toute manière. Il m'a aussi demandé de participer à la vidéo promotionnelle pour l'an prochain, ce que je ferai demain matin (heure à déterminer).
J'ai pris des notes durant toute la rencontre, et je ne les reproduirai pas ici (on a discuté de ce qui s'est bien et moins bien passé; c'est des détails logistiques), mais pour l'essentiel, ça s'est bien passé ce soir et toute la semaine, et la rencontre de ce soir a duré une heure et demie.
Je reviens à l'hôtel pour mon dernier dodo avant de revenir à la maison.
Dernier petit matin, car je pars tantôt. Bagages, café, préparatifs de dernière minute...
J'ai préparé un petit mot pour les participant(e)s à mon cours de la fin de semaine dernière car je leur dois encore de petites mises à jour de dernière minute, et je voulais qu'elles / ils sachent que je ne les ai pas oubliés.
Pour la vidéo, voir https://www.youtube.com/watch?v=MfEaVGImzfo
On commence vers 8 h 5.
Jon Kalb et Phil Nash accueillent Herb Sutter. Herb Sutter commence par dire à quel point il apprécie cet événement, qu'il compare à un Woodstock de la programmation en C++. Lui et Jon Kalb sont tous deux d'avis que c'est le meilleur événement du genre que nous soyons parvenus à mettre en place. Herb Sutter rappelle que nous devons aller ailleurs l'an prochain (nous sommes devenus trop gros pour l'endroit), et que c'est triste car nous étions bien ici, mais que c'est une belle réussite pour ce dernier événement local.
Phil Nash dit que Simon Brand a fait quelque chose d'amusant hier soir durant les Lightning Talks. Jon Kalb dit que quelqu'un a donné une présentation déguisé cette semaine. Il ajoute que c'est la première fois que toutes les plénières sont appréciées de manière à peu près unanime. Herb Sutter apprécie particulièrement le discours de Kate Gregory sur la simplicité. Jon Kalb dit que plusieurs entreprises demandent des algorithmes à leurs candidat(e)s et ne regardent plus les solutions qui ne sont pas simples.
Herb Sutter dit que les cours le plus importants qu'il ait suivi à l'université étaient Structures de données, et un cours de programmation dans lequel à chaque semaine il y avait un travail à faire dans un langage différent (un mode de pensée différent). Herb Sutter se dit en faveur d'une plus grande variété de langages, et rappelle que les langages populaires aujourd'hui ont piqué les lambdas aux langages fonctionnels. Il fait aussi l'éloge de l'échec dans la recherche, car c'est du progrès.
Phil Nash demande à Herb Sutter s'il souhaite parler de ses nouvelles exceptions. Herb Sutter dit qu'il préférerait en parler l'an prochain; il y a plusieurs propositions pour résoudre le même problème, et c'est un premier jet pour une solution de son cru. Jon Kalb pense que les exceptions sont sous-utilisées et mal utilisées, et que la proposition de Herb Sutter est un grand pas en avant. Le modèle de gestion des déceptions lui semble merveilleux, mais le modèle existant est trop dispendieux. Herb Sutter dit qu'il y a des gens qui critiquent le fait qu'on n'a pas encore réglé le problème de l'optimisation des exceptions existantes, mais qu'on veut surtout rendre les exceptions déterministes en temps et en espace. Herb Sutter rappelle que les trucs comme std::any ont des coûts mais sont opt-in.
Jon Kalb rappelle qu'on pensait initialement que connaître le type levé d'une exception était important, jusqu'à ce qu'on s'aperçoive que ce qui compte vraiment est de savoir si une exception est susceptible d'être levée. Nous avançons. Herb Sutter dit que le déterminisme et les exceptions dynamiques demeure un problème non-résolu, et que les derniers articles sur le sujet remontent à 2004... et sont de Bjarne Stroustup. Jon Kalb rappelle que la gestion d'erreurs est un problème universel, et qu'une solution générale demeure nécessaire... Les exceptions, sous une forme ou l'autre, semblent encore et toujours requises.
Jon Kalb pense que le logiciel est quelque chose sur lequel on peut construire, dans la mesure où les interfaces sont respectées (c'est une situation différente de celle dans plusieurs champs de l'ingénierie). Herb Sutter rappelle que le titre de sa proposition est Zero-Overhead Exceptions, mais qu'il aime bien Statically Typed Exceptions aussi (ça porte bien l'idée). Aussi, Herb Sutter pense que la bifurcation de la communauté de programmeuses et de programmeurs entre « utiliser les exceptions » et « ne pas les utiliser » (ou ne pas les utiliser systématiquement) crée des dialectes. Herb Sutter critique les API avec mode dual de gestion d'erreur comme <filesystem>.
Herb Sutter dit travailler très fort pour qte std::error n'ait pas de valeur zéro / none. Il ne veut pas que ce canal de sortie serve à rapporter de l'information lors d'un succès. Il critique le recours aux exceptions pour sortir d'une situation profonde (explorer un graphe) avec un succès. Phil Nash pense que le seul irritant de la proposition de Herb Sutter est que les erreurs peuvent être utilisées pour des cas non-exceptionnels. Herb Sutter pense que Use Exceptions In Exception Situations est trop informel; selon lui, une erreur naît de l'incapacité d'atteindre les postconditiosn annoncées dans un contrat. Phil Nash lui rappelle qu'il est l'auteur de la série Exceptional C++; Herb Sutter dit que ça le suit... On rit un peu.
Jon Kalb demande où cette proposition en est rendue dans le pipeline. Herb Sutter dit que les binaires deviennent plus petits et que les programmes deviennent plus rapides. Son approche se veut holistique : être opt-in, ne pas rapporter les violations de préconditions mais bien les violations de postconditions (donc std::logic_error ne devrait pas exister), le cas Out of Memory (qui ne peut probablement pas être géré; on pourrait remplacer bad_alloc par terminate()), et le modèle de programmation (que certains abhorrent) qui rend le flux de contrôle invisible, et qui serait adressé par la possibilité de mettre try devant toute expression susceptible de lever une exception.
On ferme vers 8 h 50.
C'était fort intéressant tout ça.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Je me rends au théâtre où John Lakos va nous instruire. Ses présentations sont toujours denses, riches et instructives.
John Lakos : je vais commencer à l'heure pile car je dois faire entre 90 minutes de matériel en 45 minutes. John Lakos se présente rapidement, et remercie Nathan Sidwell d'avoir fait une mise à jour de l'état de la situation dans le développement des modules plus tôt cette semaine.
John Lakos : le problème est que le développement de logiciel à grande échelle est multidimensionnel. Il promet une nouvelle version de son (excellent!) livre pour la fin de l'année. Ce qui l'intéresse est le design physique du logiciel, des modules, des composants.
John Lakos fera un survol des composants (son approche pré-module), puis de cette nouvelle entité que sont les modules. Il a quatre parties, mais ne fera que les deux premières (il lui faudrait quatre heures pour tout faire).
John Lakos montre graphiquement les modules et les composants. Un module est physique; ce qui précède (un composant) était une paire .h/.cpp. Un module est testable. Les modules remplaçent des horreurs qui ont fait leur temps.
John Lakos : un module a quatre propriétés : le .cpp inclut son .h en tant que première ligne substantive (même si le .cpp est vide outre cela); toutes les constructions logiques avec linkage externe qui sont définies dans le .cpp sont déclarées dans le .h, ce qui introduit un nom (il fait un tour de déclarations, définitions, linkage avec exemples pleins de pièges); toute entité avec linkage externe ou " bindage " (nom inventé, qui a trait aux outils : il pense à template, fonctions inline) dual déclaré dans un .h est défini dans le module; la fonctionnalité d'un module est exposée dans un .h et jamais par déclaration a priori.
John Lakos fait une critique des classes internes, que je ne partage pas, mais que je comprends dans son discours.
John Lakos décrit des relations comme Is-A, Uses-in-the-interface, Uses-in-the-implementation, Uses-in-name-only et Depends-on entre les classes dans des modules distincts. Il montre que les modules, en contrôlant l'exposition des classes qu'il contiennent, participent à un design sain. Depends-on est une relation entre modules, pas entre classes. Il quantifie le niveau de dépendances des modules.
John Lakos : les deux principales règles de design sont (a) aucune dépendance circulaire physique et (b) pas d'amitié à longue distance (il y a aussi (c) : pas de dépendances transitives). Les critères pour co-localiser des classes sont (a) l'amitié, (b) les dépendances cycliques, (c) une seule solution, et (d) une mouche sur un éléphant, pas le contraire. John Lakos note qu'il n'y a pas de coûts effectifs à avoir plusieurs petits modules.
John Lakos insiste ensuite sur l'importance de l'isolation; il distingue encapsulation logique et isolation physique. L'isolation permet des modifications locales, sans recompilation des autres modules. Il mentionne pImpl au passage. Il montre comment inclure un en-tête au mauvais endroit introduit des dépendances transitives, ce qui est très méchant. John Lakos pose la question : si j'ai une boîte faite de deux points, dois-je exposer le type point? Et la réponse est oui, du fait que chaque point participe à la taille de la boîte.
John Lakos : un .h doit être autosuffisant. Cinq raisons : Is-A, Has-A (mais pas Uses!), inline, enum (il y a des subtilités depuis C++ 11) et typedef / using. Les types de retour covariants sont un cas limite. Plusieurs questions s'ensuivent (diapos 133; voir la présentation)
John Lakos : on entre dans les requis d'affaires des modules. Il y a des horreurs du passé qui ne survivront pas au passage aux modules. Le but est de soutenir de meilleures bases architecturales pour C++, pas d'aller plus rapidement. Les modules doivent être (a) purenent additifs, (b) hiérarchiques, (c) incrémentaux, et (d) interopérables (sans provoquer de violation d'ODR). Les modules doivent donc éviter les inclusions transitives. John Lakos voir un intérêt à l'exposition partielle de classes, des vues, même en y allant un membre à la fois. Le recours aux Wrappers devrait fondre. Le caching est un sujet d'intérêt, mais on ne veut pas dépendre là-dessus pour garder la possibilité de réaliser des Builds parallèles.
John Lakos : on veut réduire le temps de compilation, réduire (mais pas éliminer) les macros, et changer le Look and Feel de C++. Faut être capables d'écrire et d'entretenir de vastes bases de code. Nous devons être capables de générer toute unité de traduction de manière indépendante.
Pablo Halpern : quel âge ont tes diapos?
John Lakos : elles ont été faites en 2009, et tiennent encore la route.
Q : vous dites qu'on ne peut écrire un Logger sans macros. Devrait-on changer le langage?
John Lakos : les macros aident à la syntaxe dans ce cas.
Q : vous avez parlé d'exposer les dépendances transitives; risque-t-on d'exposer une interface trop large dans un module?
John Lakos : on aura un entre-deux : le compilateur voit tout, pas le client.
Une solide présentation sur l'ingénierie logicielle.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
Il y a un moment entre la présentation de John Lakos et celle d'Odin Holmes. Bob Steagall me contacte pour que j'aille faire une entrevue promotionnelle, et en allant vers cette entrevue je me fais accrocher par le toujours sympathique groupe #include<C++> qui prend une photo (dans laquelle je suis désormais).
Je me fais aussi accrocher par quelqu'un qui semble avoir apprécié ma présentation de mardi après-midi. Ça fait toujours du bien!
Odin Holmes commence en disant que sa barbe a poussé... parce qu'il fait beaucoup de développement de niveau " noyau " ces temps-ci. Il parlera des difficultés associées à la synchronisation en situation de concurrence avec des ISR (Interrupt Service Routines). Il dit que la plupart des gens ont soit aucun problème... soit un problème insoluble. Il examinera :
Odin Holmes fera un retour sur ce que fait un processeur, fera une application naïve, qui échouera, examinera pourquoi, examinera les ennuis avec les solutions matérielles, puis les solutions logicielles. Il montre une abstraction du processeur (diapo, 17) qui est en soi un mensonge. Il montre la magie d'une addition, et rappelle que C = A + B demande trois adresses, donc beaucoup de bits. Avec des instructions sur 16 bits, il montre comment il est possible de représenter une telle opération sur la base de registres (les adresses utilisent trois bits chacune, donc on se limite aux registres R0 à R7 par exemple).
Odin Holmes rappelle avoir déjà travaillé sur une machine où la mémoire n'était pas contiguë, empêchant l'implémentation d'un programme C++.
Odin Holmes : le processeur a des états qui ne sont pas adressables. Entre autres, certains registres (R15, le program counter sur son démonstrateur) est mis à jour à chaque tic d'horloge. Implémenter une gestion de pile à ce niveau n'est pas insurmontable, mais est difficile. On tend à utiliser des abstractions peu coûteuses pour réduire les coûts d'entretien. Il dit avoir déjà implémenté un équivalent des exceptions statiques en utilisant deux adresses de retour (erreur, succès), mais recommande de ne pas le faire sur un poste avec Branch Prediction.
Odin Holmes montre un vieux téléphone qui avait des fonctionnalités... étranges, si on s'en servait autrement que quand on l'a testé. Il montre un main() simpliste avec boucle infinie lire() / refracihir_ecran(). Lire implique vérifier le voltage associé à la pression d'une touche. Le travail se fait pendant que la touche est pressée, pour ne lire qu'une touche pour la durée où la touche est pressée. Si on ne regarde pas assez rapidement, on peut manquer une touche. Il y a un enjeu de latence, en réaction à un événement physique par exemple.
Odin Holmes : pour combattre la latence, on peut utiliser des threads. L'un serait main() qui appelle a() qui appelle b(), mais faut une pile d'exécution par thread et faut pas déborder, et faut enregistrer l'état des registres en basculant d'un thread à l'autre. Dans un contexte de temps réel, on vient d'ajouter pas mal de latence avec ces changements de contexte. Sa diapo 51 est excellente (système orienté débit, système interactif, système TR strict).
Odin Holmes : il y a aussi une question d'échantillonnage
pour du traitement de signal (vidéo, audio). On veut que l'échantillonnage soit
stable; le jitter (qui n'est pas la latence) crée des artéfacts
déplaisants / inacceptables. Ainsi, il se peut que l'on puisse régler le
problème avec des threads, si la latence demeure sous contrôle (si on
contrôle le pire cas!), mais le jitter est un autre enjeu. Faut donc
un truc pour ne pas avoir à mettre tous les états du processeur en cache, et
pour ne pas avoir à gérer plusieurs piles d'exécution (surtout qu'elles tendent
à se rencontrer au centre sur des systèmes aux ressources limitées). Il parle
au passage d'algorithmes Data Invariant
Odin Holmes on peut faire un suivi prudent des états mutables de nos threads tant que les exécutions se rendent à la fin. Des enjeux comme être " signal-safe " et " être réentrant " deviennent importants... et la bibliothèque standard ne donne pas de telles garanties. C'est un travail manuel qui implique de faire participer l'éditeur de liens.
Odin Holmes : discute des enjeux de réactions à une interruption (entre autres, qui l'a provoquée? Une autre l'a-t-elle remplacé depuis le déclenchement?). Il a un cas :
void some_ISR() { global_thing++; }
int main() {
--global_thing;
}
Odin Holmes rappelle que volatile n'aide pas ici. Il demande comment corriger la situation, mais les gens sur place disent " désactiver les interruptions ". On serait tenté d'utiliser une atomique, mais c'est typiquement pas implémenté. Désactiver les interruptions est possible, mais il y a de la latence pour le faire. Écrire du code machine peut aider, mais il y a un risque de réordonnancement. Le réordonnancement peut même se faire entre deux accès à une même variable volatile.
Odin Holmes : si on ne parvient pas à faire notre tâche, on vit une famine. Comment valider le code? Une revue de code assembleur optimisé, c'est plus ou moins une solution... Il y a un aspect " prière " dans tout ça, qui rend malheureux. En gros :
Odin Holmes relate une histoire du drône d'un ami suédois (Emil Fresk), drône qui s'est écrasé suivant un crash logiciel. Il dit qu'il applique des approches RAII pour éviter ce genre de problème en pratique.
Odin Holmes : peut-on utiliser tous les mots du Core Language sur ces appareils? Il mentionne les Magic Statics, inimplémentables sans désactiver toutes les interruptions. Ça pose des ennuis, mettons. Il relate une histoire d'un stagiaire qui avait un bogue avec un programme d'une ligne : toupper(). Chip is Full.
Odin Holmes : metaprograms trump macros, therefore C++ is better than C
Q : quelle est la part du problème qui disparaît avec de vraies atomiques?
Odin Holmes : la question est " qu'est-ce qu'une vraie atomique? ". On peut les implémenter par CAS, si le processeur le supporte, et on peu parfois le simuler s'il ne l'est pas. En ce sens, oui, cela serait utile.
Q : et les coroutines?
Odin Holmes : elles sont merveilleuses... en théorie. Faut modéliser un automate, ou mettre une coroutine qui est du sucre syntaxique. Dans tous les autres cas, la taille et la disposition de la pile ne sont pas observables, et l'optimiseur peut les déplacer; avec vectorisation, la pile pourrait même grossir. Si une coroutine fait un co_yield, faut que l'état intermédiaire soit dans une variable nommée, ce qui crée un état observable. On peut faire semblant de l'allouer dynamiquement, et laisser l'optimiseur corriger la situation... mais si on surcharge operator new, ça devient compliqué.
Q : peut-on identifer les statiques locales avec des outils?
Odin Holmes : oui. On peut aussi regarder ce qui sort de l'éditeur de liens.
Bon boulot, mais pas pour tout le monde. Temps d'aller vers la rencontre du comité de planification.
La rencontre débute vers midi. J'ai croisé Eva Conti qui a géré mes problèmes avec l'hôtel (qui voulait me charger mon séjour... Ça aurait fait quelques milliers de dollars!), et j'en ai profité pour la remercier.
La planification est un truc administratif, alors je n'entrerai pas dans les détails. C'est Bob Steagall qui est en charge de la rencontre.
Pour la prochaine année, il y aura des appels conférences pour préparer divers aspects de l'événement. On discute brièvement des moments des appels, mais il est difficile de savoir quand les faire. Le plus probable semble être midi à mon fuseau horaire.
J'ai fini par être secrétaire de la rencontre. C'était surtout intéressant car même si on ne nous l'a pas dit formellement, je sais maintenant où se tiendra l'événement l'an prochain (certains indices ne trompaient pas).
Il me reste deux présentations, soit celle de Ben Deane, qui sera assurément excellente, et le keynote de Chandler Carruth (toujours excellent lui aussi). Je vais malheureusement manquer le panel de la fin car j'ai mon avion à prendre et je m'ennuie vraiment de mes enfants et de mon amoureuse.
Pour la vidéo, voir ceci
Pour les diapositives, voir ceci
On commence à l'heure.
Ben Deane : notre langage est multi-paradigme, et admet plusieurs styles. Je vais essayer de situer ce style dans une perspective historique, et de donner des exemples concrets et utiles.
Ben Deane : quelques signes du style déclaratif :
Ben Deane : les expressions se composent sous plusieurs axes, étant faites de sous-expressions. Les énoncés sont exécutés en séquence... et c'est pas mal ça. On a des séquences, des contraintes implicites, une validation minimale... C'est moins puissant
Ben Deane : dans un style déclaratif, on réduit les énoncés au minimum. Moins de sélections, d'itérations, de sauts, etc. En particulier, les affectations sont des expressions... C'est un choix historique qui ne nous aide pas, et mieux vaut les éviter (sinon, on finit par faire des horreurs comme des Yoda Conditions). Ben Deane critique le choix de = pour l'affectation, mais en présente les bases historiques. Il critique aussi le choix de = pour affectation et pour initialisation, deux opérations différentes. Efin, il est d'avis qu'enchaîner les affectations est une forme de paresse syntaxique.
Ben Deane : aveec un style déclaratif, on préfère les appels de fonctions. Il suggère de remplacer le verrouillage d'un weak_ptr suivi de l'utilisation d'un service du pointé si le pointeur est non-nul par un if-init, puis il suggère de passer par le ternaire, puis il invente un ternaire-init, puis il imagine un statement-expression, puis il finit par une IIFE et une interface optional-like (avec valeur par défaut suppléé par le client). Il passe ensuite à une interface monadique.
Ben Deane : allons vers la pratique déclarative existante. Quelques pratiques à adopter :
Ben Deane : return est le goto socialement acceptable. En plus, on a RVO! Aussi, on préfère les algorithmes aux boucles.
Ben Deane : les tests sont très déclaratifs (souvent avec des macros...). Ils sont idempotents, n'ont que peu ou pas de dépendances temporelles entre eux, etc. Il discute ensuite de journalisation (logs) déclarative. Un appel à fprintf() où il faut passer un flux (global?) en tant que destination est remplacé par une classe, qui encapsule la destination à la construction (tiens, tiens!) et un prédicat pour accepter ou pas un paramètre pour fins de journalisation. Il enchaîne par un multisink, et par un nullsink. On peut encapsuler la condition dans la classe et rendre le point d'appel déclaratif.
Ben Deane : plusieurs schémas de conception sont naturellement déclaratifs. Il mentionne Null Object, Command, Composite... et une variante de Builder, par enchaînement de fonctions retournant une référence sur *this pour faciliter la mécanique. Il sort un exemple de cédule avec un enchaînement de .then(). Il fait remarquer qu'il y a peu de verbes dans le code déclaratif. Il se dit heureux que les règles d'ordre d'évaluation des expressions soient plus claires avec C++ 17.
Ben Deane : il montre une technique pour permettre la construction étapiste d'un objet complexe, mais ne l'accepter en paramètre à une fonction que si certaines étapes de construction ont bel et bien été faites (diapos 62-64)
Ben Deane : quelles sont les forces et les faiblesses de C++ pour ce style de programmation? Pour les plus, on pense à RAII, les designated initializers, les fonctions et les lambdas (qui transforment des énoncés en expressions), les Structured Bindings pour contourner les restrictions sur les valeur de retour, la surcharge de fonctions et d'opérateurs, les templates
Ben Deane : décrie quelques incohérences aussi. Il aimerait un if-en-tant-qu'expression, entre autres.
Ben Deane : il reste tout de même des " bouées de sauvetage " impératives : on peut raffiner les attributs, utiliser [[nodiscard]], utiliser l'analyse statique, [[fallthrough]], les if-intializers.
Ben Deane : les fonctions de la bibliothèque standard sont aussi d'un grand secours. Il mentionne std::exchange(), std::as_const(), std::apply()... Évidemment, tout ce qu'il y a dans <type_traits>, et bien sûr optional<T>
Ben Deane : exprime une lambda identity (tu lui donnes a, elle retourne a) et une lamnda always (tu lui donnes plusieurs choses, elles retourne toujours la première rencontrée)
Ben Deane montre comment remplacer les conditionnelles selon les styes de programmation (diapo 77). Ces remplacements, s'ils vont plus creux sur la pile d'exécution, nous mènent à du code sans fuites, avec des interfaces monadiques; s'ils vous plus haut, donnent des fonctions d'ordre supérieur, de l'injection de dépendances, etc. Le but est de travailler en mode " total fonctions ", pour qu'il soit plus facile de raisonner.
Ben Deane : remplacer l'affectation mène à une déclaration au point d'utilisation (plusieurs autres trucs chouettes)
Ben Deane : les interfaces déclaratives se composent bien et facilitent le raisonnement.
Q : le type de requête... Pourquoi ne pas avoir accepté les types à la construction?
Ben Deane : on aurait pu, mais ça aurait fait beaucoup de combinaisons
Q : que veux-tu dire par " identifier les monoîdes "?
Ben Deane : c'est une manière de réfléchir à la composabilité
C'était bien, mais je code déjà beaucoup comme ça. J'y ai trouvé mon compte.
Pour la vidéo, voir https://www.youtube.com/watch?v=_f7O3IfIR2k
Pour les diapositives, voir ceci
Ceci devrait être très intéressant. Le panel qui suivra aussi, mais je serai en route vers l'aéroport.
Jon Kalb fait les messages d'usage, et Bob Steagall présente les gagnant(e)s du concours de posters. Il dit que l'on est arrivés à trois gagnant(e)s plutôt que deux, car un poster était suffisamment imaginatif et surprenant pour mériter qu'on crée une catégorie juste pour lui. Il invite les gens sur place à participer l'an prochain. Jon Kalb remercie tout le monde pour avoir respecté le code de conduite, et dit qu'il nous indiquera où nous serons l'an prochain suite au panel.
Eva Conti présente Chandler Carruth.
Chandler Carruth explique ce qu'est Spectre, ce très, très vilain problème de sécurité. Il rappelle qu'il a donné une présentation sur l'exécution spéculative l'an passé et qu'on lui avait posé une question sur ce qui se passe quand l'exécution spéculative dérape. Il avait mal répondu, d'où la présentation cette année.
Chandler Carruth : je ne veux pas parler d'exploitation, mais bien de vulnérabilités. Je ne veux pas parler d'attaques, mais bien de mitigation. Aussi, si vous voyez de nouveaux vecteurs d'attaque, ne venez pas les révéler au micro devant mille personnes, venez me parler de manière responsable et privée.
Chandler Carruth : quand j'ai commencé à me battre contre cela, je ne comprenais pas tout à fait ce que je faisais. (il explique un peu de vocabulaire, puis parle de Heartbleed). Je vais vous montrer à quoi ressemble une fuite d'information. Il utilise un programme qui valide mal ses intrants et laisse fuir des informations secrètes.
Chandler Carruth : un Side Channel est un mécanisme pour transporter de l'information à travers les mécanismes normaux du système (par opposition à un Covert Channel). Il donne encore une fois une démonstration, qui utilise quelques vilaines techniques pour aller toucher toutes les Cache Lines en lecture et comptabiliser les latences moyennes d'accès. Il parvient à aller chercher des informations secrètes à travers cette manoeuvre.
Chandler Carruth : l'exécution spéculative permet au processeur de réaliser des calculs juste au cas, quitte à reculer s'il s'est trompé. Il montre en gros Spectre v1 et la fuite que cela provoque. Il montre que du code correct, avec validation, peut charger des informations hors bornes dû à l'exécution spéculative
Chandler Carruth : le problème ici est la combinaison de l'exécution spéculative jointe aux Side Channels. Cette joyeuse combinaison crée une nouvelle (et violente!) famille de bogues de sécurité. Plusieurs autres du genre (nouveaux Side Channels, nouvelles techniques) sont apparus en peu de temps. Une vingtaine (au moins) d'histoires d'horreur, certaines étant même capables de capturer de l'information d'un processus déjà terminé. Le coup le plus douloureux était NetSpectre, qui permettait de voler de l'information à partir d'une machine distante.
Chandler Carruth : l'enjeu est général : ce que Spectre a montré est que tout ce qui peut être prédit par le processeur peut fuire. Il parle de SSO, de hiérarchies de classes... Il y a même un compilateur qui ne fait qu'analyser des programmes et les attaquer...
(je dois quitter; je vais devoir la regarder sur Internet. C'est vraiment bon)
Je me suis farci un tour de taxi avec un personnage de cinéma, partisan de Trump et qui change de sujet et d'opinion à toutes les deux phrases, mais gentil avec moi et qui m'a amené à l'aéroport à temps (ce que j'apprécie; il y avait du trafic). Reste à retourner vers les miennes et vers les miens...