À propos de cppcon 2022

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 à Richard Fontaine du CeFTI) et au Collège Lionel-Groulx (en particulier à Patrick Lebonnois et à mes collègues du département d'informatique), j'ai le privilège de participer (en personne, après deux ans de présence virtuelle dû à la pandémie) à CppCon 2022. Notez que la conférence est en mode hybride cette année, mais que les circonstances font que je serai un participant (et un conférencier) en présence.

Ce qui suit est une sorte de journal de voyage (sans la partie voyage!), avec éléments humains et éléments techniques. Au besoin, référez-vous à ce glossaire : ../../Lexique/lexique-wg21.html

Notez que c'est pour moi 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é.

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

Les jours entourant l'événement

CppCon est un très gros événement, qui se tient chaque année depuis 2014 (vous trouverez mes journaux des années précédentes sur index.html avec des noms évocateurs tels que cppcon2014.html par exemple). Je participe à l'organisation de l'événement depuis le début, mais le maître d'oeuvre est Jon Kalb. Nous avons tenu l'événement à Bellevue, en banlieue de Seattle, pendant plusieurs années, avant de le déplacer à Denver en 2019 par besoin d'espace (l'hôtel où nous sommes maintenant est gigantesque). En 2019, nous avions plus de 1200 participantes et participants sur place; pour un colloque aussi spécialisé, c'est impressionnant.

Depuis le début, CppCon offre non-seulement des conférences (et beaucoup! Environ six ou sept en même temps de tôt le matin à tard le soir pendant cinq jours consécutifs, hormis les Keynotes auxquels tout le monde assiste) mais aussi des classes de maître, pré-conférence et post-conférence. J'en donne d'ailleurs moi-même depuis 2016. Ces classes se donnent habituellement la fin de semaine qui précède l'événement et celle qui le suit, ce qui fait de l'événement entier (classes incluses) quelque chose qui se tient sur neuf jours consécutifs.

Cette année, les classes de maître se donnent la fin de semaine avant et la fin de semaine après. Ma classe est Thinking Small (https://cppcon.org/class-2022-thinking-small/), juste avant le colloque.

Un gros merci au passage à mes étudiantes et à mes étudiants au Collège comme à l'Université, qui collaborent avec moi quand je dois m'absenter comme ça, et qui s'adaptent aux petites acrobaties d'horaires et de format des cours qui viennent avec le fait de m'avoir comme enseignant. J'apprécie votre ouverture. Merci aussi à mes collègues qui collaborent avec moi même si ça complique leur existence.


Je suis allé de la maison à l'aéroport en transport en commun, et ça s'est très bien passé, beaucoup mieux que je ne l'aurais cru avec des bagages. Arrivé à l'aéroport, j'ai constaté qu'il faut porter le masque en tout temps (mais j'en traine toujours un dans mes poches). Les prises de courant se font rares dans l'aéroport, ce qui est très étrange à mes yeux. J'ai pris un café et un petit sandwich poulet caprese pesto (pas mal).

Pour ce qui est du trajet en avion : j'étais à l'arrière de l'appareil, côté fenêtre; il y avait un espace libre entre moi et ma voisine (cool!), mais pas de courant pour alimenter mon ordinateur portatif (très moche). Les passagers juste devant se plaignent de beaucoup de choses (porter le masque dans l'avion, visite en sol canadien, espace pour leurs bras, etc.). Soupir...

Arrivé à l'aéroport : la cueillette des bagages se fait sans encombre. Un peu de travail pour savoir comment gérer le cellulaire sans se ruiner (merci Za pour avoir interfacé avec notre fournisseur!). J'étais supposé me faire transporter en limousine (truc circonstanciel qui tombait sur moi cette année), mais elle n'arrivait pas et on a fini par me cueillir par Uber.

À l'hôtel : bel accueil. Ma chambre est au 12e étage de la tour Nord. Il y a une petite réception pour les instructeurs au 7e étage; je pique de petites jasettes avec Jon Kalb, Klaus Iglberger, Nicolai Josuttis, Anthony Williams et Daniela Engert entre autres. Il y a de la Pizza et un peu de chocolat (merci Jon Kalb!). J'apprends qu'après un 2020 à distance et un 2021 hybride avec présence in vivo plus humble, 2022 s'annonce bien : nous avons doublé le nombre d'inscriptions en personne depuis l'an dernier, se rapprochant à peu près aux de la population pré-COVID, et nous avons encore des présentations et des inscrits qui sont à distance et s'ajoutent à ce nombre.

De retour à ma chambre, j'apporte des retouches à mes diapos et à mes exercices, incluant l'ajout de quelques liens Wandbox, pour le premier jour de classe demain matin. Puis dodo...


Debout à 5h, travail sur les diapos. Retouches, modernisation, ajout d'exemples, précisions

Bon groupe, belles interactions, questions intéressantes. Des gens très intelligents

Repas ... de pizza 🙂

Le café est bon. Collation du matin : bagels et fruits. Collation d'après-midi : petites bouchées d'empanadas poulet et fromage avec un peu de salsa

Travail à mon « bureau » en soirée (ma chambre!). Petite jasette avec Za, Ludo et mes chics beaux-parents Danielle et Jocelyn. Je leur montre ma chambre et le corridor (l'hôtel est immense, on se croirait parfois dans un film comme The Shining!). J'apprends que Pierre Poilièvre est chef conservateur... Eh ben.

Je me permets une salade (oeufs, laitue, un peu de bacon, fromage bleu, tomates) et une petite (très!) bière... à 9 USD. Total : 23 USD. Pas trop souvent, mettons. Par contre, j'ai reçu un chouette paquet des responsables de l'hôtel, avec du chocolat, du pop-corn et d'autres grignotines. Est-ce parce que la limousine nous a fait faux-bond hier? Mystère...

À 20 h 30 heure locale (22 h 30 heure de Montréal), la fatigue me frappe... Je pense que je paie pour les jours qui ont précédé, le décalage horaire et l'adrénaline de la première journée de formation.

 

Jour 0 11 septembre

Préparation le matin, incluant un peu de recherche sur les implémentations de optional<T>::operator=(const T&) en lien avec la sécurité lors de levées d'exceptions. Je parle brièvement à mon amoureuse Za et je me prépare un peu pour ma préparation de jeudi matin.

Cours se passe bien, très bien même je dirais : belle classe pleine de gens brillants qui participent et ont de bonnes idées. Goûter du matin : muffins (pas trop gros, bonne chose!) et fruits. Le midi, repas mexicain où on se sert; les bénévoles font un travail remarquable pour prendre soin des gens (une personne est en béquilles; d'autres sont végétariens et on s'assure que ces gens aient accès à de la nourriture qui leur convient, quitte à les faire passer devant les autres). Goûter de l'après-midi : une barre de crème glacée Haagen Dazs (avec alternative végane)!

Après le cours, je croise mon bon ami Billy Baker qui me convainc d'aller manger avec lui (j'essaie d'être frugal car tout coûte très cher ici). On prend une petite bouchée (pour moi : une saucisse jalapeño et cheddar, petite salade de chou, céleri et pommes, un peu de sauce pour la saucisse et un petit pain, le tout avec une bière en fût... 30 USD avant pourboire, ouf!) et on jase de la vie un peu.

Ensuite, petit tour à ma chambre, avant la réception de la soirée, pour parler à mon amoureuse Za et à mon plus jeune Ludo. Enfin, la réception de la soirée, fort agréable, où je parle avec plusieurs chics personnes (Billy Baker, Inbal Levi, David Olsen, Walter Brown, Pablo Halpern – que je remercie au passage pour son excellente conférence sur les littéraux maison), Ben Searles, Daniel Hanson, Tim van Deurzen, David Stone, et j'en oublie). Je quitte à mi-chemin, car je suis fatigué, et je croise Herb Sutter et Bjarne Stroustrup qui arrivent et semblent d'excellente humeur... Je pense que tout le monde est content de se revoir!

Jour 1 12 septembre

Debout tôt car les présentations vont de 6 h 45 à 22 h aujourd'hui. Je m'occupe par couriel de quelques étudiant(e)s qui ont soit oublié les consignes de remise d'un travail récent, soit oublié que je ne suis pas au poste cette semaine et se sont présenté(e)s devant une classe vide... Hé la la...

C'est l'anniversaire de mon beau-papa Jocelyn et de mon amie Kim Valiquette aujourd'hui, alors j'écris un (trop bref) mot à chacun avant de me mettre en marche. La présentation de Lisa Lippincott est à 6 h 45 heure locale. C'est tôt alors il y a encore peu de gens à mon arrivée; Jon Kalb fait quelques tests en lien avec ce qui sera, je suppose, sa prise de parole avant le Keynote de Bjarne Stroustrup, et il profite de ce moment pour expliquer aux gens qui participent à distance comment l'événement se déroulera de leur côté. On nous présente une vidéo par Guy Davidson qui est pris en Angleterre et qui est en charge du respect du code de conduite, chose incontournable désormais. Ça commence sur les chapeaux de roues!

Lisa Lippincott est une intellectuelle d'une grande profondeur, et une personne très agréable à côtoyer. La salle est déjà à moitié pleine à 6 h 45 et ça continue d'entrer.

Vidéo : https://www.youtube.com/watch?v=0TDBna3PWgY

Lisa Lippincott – Principia Mathematica, the Foundations of Arithmetic in C++

Lisa Lippincott se présente et explique le titre (osé!) de sa présentation, qui évoque le célèbre texte d'Isaac Newton, mais dans son cas le célèbre texte de Bertrand Russell et Alfred North Whitehead, soit le triomphe (dans une certaine perspective) de la philosophie selon laquelle les mathématiques sont exprimables à partir de principes fondamentaux de logique. Elle présente la page 86 du volume 2, célèbre pour démontrer que... .

Lisa Lippincott dit que le Principia... original prend son temps pour expliquer ses idées, mais qu'elle ira un peu plus vite 🙂 Elle associe l'idée de types à Bertrand Russell, dit qu'elle parlera de théorie des catégories, et prend son titre selon deux angles en plaçant des parenthèses : The foundations of (arithmetic in C++) et (The foundations of arithmetic) in C++ 🙂 Elle dit qu'elle compte exprimer les fondations des mathématiques à partir de C++, et que c'est un bien meilleur langage pour ce faire que tout ce qui était disponible à l'époque du Principia...

Lisa Lippincott utilisera sa classique définition d'interfaces de fonctions, avec un prologue (incluant les préconditions(, une implémentation et un épilogue (incluant les postconditions), et exprimera tous les opérateurs arithmétiques, relationnels et logiques de cette façon. Elle revient sur des idées des années précédentes à l'effet que les propriétés souhaitables des fonctions sont Stability, Subtitutability, Repeatability. Faudra voir la présentation pour les détails car ça bouge vite et ça demande de l'attention... C'est super intéressant comme vision des opérateurs!

Lisa Lippincott mentionne qu'une de ses notations pose problème : elle montre que a==b signifie que si a==b alors claim substitutable(a,b) mais que des alternatives (if) dans un prologue est typiquement un mauvais design du fait que les préconditions sont la responsabilité de l'appelant.

Lisa Lippincott utilise ensuite son formalisme pour définir les opérateurs, débutant par l'affectation d'un entier à un autre. C'est intéressant, et ça peut servir de fondation conceptuelle aux contrats qui sont des formalismes de validation des valeurs (là où les concepts sont des formalismes similaires mais applicables aux types). Elle construit un formalisme profond pour représenter une infinité de types entiers, incluant ceux qui sont déjà standardisés, et exprime visuellement et brillamment l'idée de promotion arithmétique de même que celle de coercion arithmétique (Narrowing Conversion). C'est vraiment une excellente présentation!

Lisa Lippincott exprime les étrangetés que sont ++ et -- à partir de fonctions inventées next() et previous() pour être en mesure d'utiliser un raisonnement fonctionnel. Dans sa notation, les versions suffixées sont un peu plus complexes que les préfixées car l'objet sur lequel on opère n'est pas sustituable avec l'opérande.

Lisa Lippincott explique ensuite que pour son formalisme, il est préférable de se débarrasser des types entiers plus petits que int (comme le fait d'ailleurs C++) et leur appliquant une promotion à int ou à unsigned int selon le cas. Elle discute des étrangetés des types de caractères et de ces types mensongers que sont les champs de bits.

Lisa Lippincott présente template <class T> using promoted_type = decltype(+std::declval<T>()); car le + unaire est l'opérateur de promotion arithmétique... Je n'ai pas vu venir celle-là 🙂 Elle définit un formalisme de promotion et de démotion de types, et un mécanismes d'identification de type vers lequel réaliser une promotion dans le cas d'opérations à types mixtes. Avec ces formalismes, elle exprime l'arithmétique sur des types différents.

Lisa Lippincott discute des glissements (<< et >>) qui ont des comportements différents des autres sur le plan des conversions. Elle discute aussi de / et % qui ont des coins sombres, mais met en relief que ces enjeux sont en fait des préconditions, pas des postconditions (en gros, pour un type entier signé T, numeric_limits<T>::min()/-1 est indéfini). Une phrase prise de [expr.pre] est un peu violente... Lisa Lippincott examine quelques passages choisis du standard et met en relief les préconditions et les postconditions.

Lisa Lippincott crée une classe widening<integer_kind k> pour exprimer certaines transformations qui demandent de passer par un type plus grand que celui des opérandes, et pour simuler un passage temporaire par l'ensemble théorique des entiers relatifs.

Je n'ai pas tout pris en note, mais je vous recommande de regarder ceci avec attention quand ce sera publié. Lisa Lippincott définit l'addition entre deux bits d'une manière qui rappelle la difficulté (célèbre!) d'exprimer dans le Principia... 🙂

Lisa Lippincott explique par la suite qu'une fois toutes les interfaces définies, il devient possible d'exprimer des preuves, des théorèmes. Elle exprime par exemple que l'addition est commutative en quelques lignes.

Lisa Lippincott termine avec une intéressante critique de la vision platonique et idéaliste de l'arithmétique des entiers relatifs, et recommande une pensée à partir des entiers représentables.

Pas de questions, mais wow!

Brève jasette avec Lisa Lippincott ensuite car j'avais une question sur sa notation. Je me déplace ensuite vers la salle de bal où se tiendra le Keynote de Bjarne Stroustrup ce matin, sur un sujet qui m'intéresse en plus. C'est une bonne marche (l'hôtel ici est gigantesque, et la marche entre les deux salles demande plusieurs minutes). Comme c'est la tradition ici, un band rock anime la salle. Je m'attendais à voir quelque chose à manger en cours de route (il y a souvent des fruits et du yogourt), mais je n'ai rien vu de tel. Heureusement, il y a du café, et on passe par divers exhibits technologiques présentés par des gens sympathiques.

Jon Kalb prend la parole et présente à la fois l'événement, les commanditaires, les règles associées au code de conduite, etc. pour enfin introduire Bjarne Stroustrup (qui n'a pas besoin d'introduction, évidemment).

Vidéo : https://youtu.be/2BuJjaGuInI

Bjarne Stroustrup – C++ in Constrained Environments

Bjarne Stroustrup dit avoir beaucoup voyagé cette dernière année, avoir parlé à beaucoup de gens, et avoir pris des notes sur ce que les gens font quand ils programment avec C++ mais avec contraintes. Il compte parler de programmation de bas niveau, de lever le niveau d'abstraction, de gestion d'exceptions, etc.

Bjarne Stroustrup met de l'avant l'important d'avoir un cadre conceptuel de philosophique pour aborder la résolution de problèmes. La plupart des systèmes amènent avec eux des contraintes de développement (limites de mémoire, contraintes du monde physique, matériel inhabituel, disponiblité, etc.), on n'a qu'à penser aux voitures sans conducteurs par exemple. Il se préoccupera surtout de fiabilité (Reliability, Dependability), de gestion de ressources, de problèmes « malpropres » et d'enjeux d'entretien à long terme. Selon lui, chercher une solution universelle est contre-productif. Il faut faire face au code de bas niveau, aux erreurs, et le faire avec élégance.

Bjarne Stroustrup rappelle que le langage (qu'on aime!) n'est qu'un outil parmi plusieurs. Il parle des nombreux autres outils dont nous avons besoin (incluant les livres de référence, les outils logiciels, la communauté, etc.). Pour faire face à une complexité croissante, il nous faut développer de meilleurs outils et de meilleures pratiques.

Bjarne Stroustrup mentionne plusieurs aberrations entendues au cours de ses voyages, par exemple que C et le « style C » de programmation est requis ou idéal pour la programmation de bas niveau. Ces croyances aberrantes qui persistent... Il rappelle qu'il est cotnre-productif d'essayer d'écrire du Java en C++, comme il est contre-productif d'écrire du C++ en Java. Il rappelle aussi qu'il est faux que tous les systèmes embarqués doivent éviter les exceptions (mais admet que c'est vrai pour certains systèmes).

Bjarne Stroustrup rappelle aussi qu'on n'a pas à utiliser tous les nouveaux mécanismes de C++ pour écrire du bon code. C++ est un langage très mature, et il n'y a pas de mal à utiliser des mécanismes qui ont fait leurs preuves. Utilisons les nouveaux mécanismes, mais quand cela s'avère raisonnable et pertinent!

Bjarne Stroustrup mentionne le principe de l'oignon : présentez une interface simple, sécuritaire et utilisable aux usagers; au besoin, offrez une alternative ou une implémentation améliorée. Éventuellement, parlez au matériel directement. Il n'est pas pertinent d'optimiser chaque ligne de code; l'optimisation est pertinente quand elle découle de choix faits à partir de métriques objectives, ou du moins d'estimés rigoureux (et on peut mesurer plusieurs aspects d'un programme).

Bjarne Stroustrup : qui écrit des systèmes sous contraintes? Un peu tout le monde, vraiment, des débutants aux gens très expérimentés, et incluant des gens qui sont experts de leur domaine qui ne sont pas nécessairement des programmeuses et des programmeurs d'une grande expertise.

Bjarne Stroustrup rappelle que les piliers qui soutiennent C++ sont une capacité d'abstraction à coût nul et une capacité de parler directement au matériel. Cela s'accompagne d'un système de types statique, de sémantiques de valeur et de référence, d'une approche systématique à la gestion des ressources, de mécanismes de programmation à la compilation et de programmation générique puissante et flexible. Tout cela en plus bien sûr d'un accès direct aux mécanismes du système d'exploitation. La mémoire est une séquence d'objets, les objets se composent par concaténation, et ce modèle se réifie directement dans le matériel d'une manière qui favorise une exécution rapide et efficiente.

Bjarne Stroustrup indique que le modèle machine de C++ est une abstraction, et que le matériel en soi est extrêmement varié. Il parle de l'importance d'exprimer l'intention dans le code, de créer des abstractions vérifiables (et auto-vérifiables!). Il distingue en ce sens variant (qui exprime une intention et est vérifiable) et union (qui ne fait pas ces choses).

Bjarne Stroustrup enjoint les gens présents à préférer les données immuables : const, constexpr, consteval, constinit sont des idées importantes. Initialisons nos variables (outre dans les cas où c'est redondant, par exemple déclarer une variable pour ensuite y lire une valeur par voie d'un flux).

Bjarne Stroustrup parle de manipulation de bits, et recommande de faire ce qui est nécessaire. C'est difficile et dangereux, alors il faut faire des choix raisonnés et prudents. Ce qu'on veut est élever le niveau d'abstraction, et profiter du Zero Overhead Principle (qu'il distingue de Zero Cost... car You Pay For What You Use après tout) pour raisonner à l'aide de classes, de templates et autres mécanismes. Définir ses abstractions par des types aide au raisonnement formel, aux preuves, aux tests et à la compréhension.

Bjarne Stroustrup poursuit avec la gestion des ressources, ces choses qu'on acquiert, qu'on utilise et que l'on libère (en C++, qu'on peut libérer implicitement dû à la finalisation déterminste des objets) et qui incluent la mémoire sans s'y limiter. L'idiome RAII est mis en valeur, comme il se doit. Ces mécanismes permettent à la fois d'écrire du code expressif, qui gère les ressources de manière sécuritaire, et qui permettent d'atteindre des seuils de « performance » optimaux.

Bjarne Stroustrup explique qu'om peut ensuite déplacer une partie de l'effort de l'exécution vers la compilation. Ceci part de l'inlining à la surcharge de fonctions, à l'élision de copies et au mouvement, aux méthodes virtuelles, aux fonctions membres, aux fonctions constexpr et consteval... Et C++ permet de réaliser les calculs à la compilation sans les limites aux types primitifs (il donne l'exemple de <chrono>). Observation intéressante : en C++, les calculs faits à la compilation peuvent sembler invisibles. Bjarne Stroustrup mentionne les efforts héroïques de Matt Godbolt (on t'aime Matt!) pour nous aider à visualier ce que nous faisons.

Bjarne Stroustrup présente les Core Guidelines et quelques bons livres pour aider les gens à accroître la qualité du code qu'ils produisent. Il se dit d'avis que créer des « sous-ensembles sécuritaires » de C++ est un cul-de-sac. (je perds quelques passages car je réponds à des questions d'une chic bénévole qui est ici pour se familiariser avec C++ et la communauté, et qui se demande où aller aujourd'hui). Bjarne Stroustrup distingue la manipulation de bas niveau à partir de pointeurs et l'équivalent, de plus haut niveau et à coût nul, à partir de span. Il met aussi l'accent sur l'apport de la sémantique de mouvement.

Bjarne Stroustrup parle de portée et de la gestion de la vie des objets, rappelant ce à quoi il importe de faire attention pour éviter les fuites et les accès à des objets hors-portée. Il rappelle l'intérêt d'utiliser des conteneurs plutôt que d'avoir recours à des mécanismes comme les pointeurs bruts pour lesquels la responsabilité sur la ressource est imprécise.

Bjarne Stroustrup enchaîne avec une discussion sur la gestion des erreurs à l'exécution, et sur l'importance de la simplicité dans le code. Nous faisons toutes et tous des erreurs après tout. Les requis en ce sens dépendent du contexte et du domaine d'application; de même, comme il y a plusieurs sortes d'erreurs, il y a plusieurs stratégies de gestion des erreurs. Entre autres, nous avons besoin à la fois de codes d'erreurs et d'exceptions, peu importe la forme que ces deux idées prennent en pratique. Il mentionne que les exceptions sont nécessaires en particulier pour les constructeurs bien sûr, mais aussi pour les opérateurs et pour les Callbacks. Il mentionne des techniques pour ramener le coût de la gestion d'erreurs par levée d'exception à coût essentiellement nul si aucune exception n'est levée. Mention intéressante : il arrive que le traitement des erreurs occupe la part la plus importante de l'espace dans un programme... et que ce soit là qu'on trouve le plus d'erreurs! Bjarne Stroustrup offre un bon survol des approches au traitement des erreurs, sur plusieurs diapositives.

Bjarne Stroustrup revient sur les fondements du langage. Il nous rappelle que le matériel devient de plus en plus étrange... Il poursuit avec ses rêves pour le futur, soit des exemples de mécanismes qui changent les manières de penser :

Bjarne Stroustrup rappelle l'apport crucial de la stabilité et de la compatibilité, et qu'il ne faut en aucun temps sacrifier la « performance » en cours de route. Certaines parties de ses rêves sont hors-langage : un système de Package Manager, un dépôt de paquetages, de meilleurs analyseurs statiques (incluant un support de la transformation automatique du code)...

(j'ai manqué les premières questions car je parlais à Marshal Clow dont le badge (le Nametag) officiel est caché par un autre badge qui l'identifie comme Inigo Montoya, avec la célèbre citation You killed my father, prepare to die 🙂 Quand je recommence à porter attention, Bjarne Stroustrup discute de l'importance des analyseurs statiques, et qu'il aimerait que ces outils reconnaissent par exemple les interfaces à base de pointeurs pour les remplacer par un équivalent à partie de span)

Q : est-ce possible d'avoir un analyseur statique offrant les mêmes garanties de sécurité que le Borow Checker de Rust?

Bjarne Stroustrup : oui

Q : vous parlez de déplacer des calculs à la compilation, mais la compilation de C++ est lente... Comment l'accélérer?

Bjarne Stroustrup : il y a pire (essayez Scala!). Essayez les modules, vous verrez une bonne différence

Q : programmer des systèmes embarqués exige un contrôle strict du matériel, ce que la bibliothèque standard ne permet pas toujours...

Bjarne Stroustrup : je ne suis pas au courant de travaux qui amèneraient des mécanismes de contrôle plus précis en ce sens ces jours-ci

Q : comment pourrait-on accéder à des concepts du matériel qui n'apparaissent pas dans la machine abstraite de C++, par exemple les registres qui contiennent les Carry Bits lors de multiplications?

Bjarne Stroustrup : c'est le genre de besoin pour lesquels il faut encore recourir à du langage d'assemblage

Q : pourquoi un(e) débutant(e) devrait-elle / il débuter son expérience de programmation avec C++ plutôt qu'avec un autre langage?

Bjarne Stroustrup : ça couvre une vaste gamme de besoins, et c'est beaucoup plus facile d'approche que certain(e)s ne le laissent entendre. Il y a une belle communauté, parlez aux gens, apprivoisez-le.

Je reste dans la même pièce car la présentation d'Andreas Weis sur les coroutines s'y trouvera. C'est un sujet difficile d'approche car nous en avons standardisé l'infrastructure, mais il faut encore écrire beaucoup de code pour en profiter car la bibliothèque standard ne comprend pas beaucoup d'outils pour nous faciliter la vie. Je suis curieux de voir son approche... Klaus Iglberger présente sommairement le Back-to-Basics Track et ses protagonistes cette semaine, mais malheureusement cela se fait sans avertissement et beaucoup de gens sont en mouvement quand il commence à faire sa brève présentation (il fait du bon travail).

Pendant la pause, je fais le plein de café. C'est à ce moment que nous avons droit à quelques bouchées (très bon : je me permets un petit muffin aux pacanes et un yogourt accompagné de petits fruits et de chapelure de type Graham). L'ambiance est très agréable ce matin (et j'ai pris un deuxième yogourt, geste de folie, car ils sont vraiment bons!). En allant au petit coin, j'ai constaté que nos voisins (un autre gros colloque dans la salle de bal voisine) sont des spécialistes de la détection des fraudes et des enquêtes sur les personnes. Ces gens sont aussi très nombreux, mais c'est si vaste ici que j'aurais pu ne jamais savoir qu'ils étaient là.

En revenant à ma place, j'ai croisi l'ami Jason Turner. Il se trouve que je porte mon vieux chandail de CppCast, sa (défunte?) balado à laquelle j'ai participé à quelque reprises, chandail qu'il m'a personnellement donné en... 2014? On fait des blagues sur l'aspect « vintage » de la chose 🙂

Vidéo : à venir

Andreas Weis – Deciphering Coroutines, a Visual Approach

Andreas Weis se présente (je le connais un peu car il est un des co-organisateurs du C++ Users Group de Munich, où j'ai donné quelques présentations par le passé).

Andreas Weis commence en annonçant que les coroutines sont difficile d'approche, du moins aujourd'hui. Il souhaite nous donner une méthodologie pour ne pas oublier les aspects importants lorsqu'on les utilise et lorsqu'on les définit (note personnelle : j'ai espoir que ce soit une présentation utile pour la pédagogie des coroutines; doigts croisés!)

Andreas Weis dit qu'il fera quelques simplifications du modèle pour les fins de la présentation et que le code des diapos est du Slideware (j'espère que ça demeurera utile)

Andreas Weis : une coroutine est une fonction dont l'exécution peut être mise sur pause. C'est plus facile de voir une coroutine comme une fabrique qui retourne un objet qui représente les états de la coroutine; il note au passage que les coroutines de C++ sont Stackless.

Andreas Weis commence avec un exemple de lecture asynchrone sur un socket. Son exemple met en relief qu'il y a une inversion de contrôle intrinsèque dans la confection d'une coroutine, mais que la syntaxe masque quelque peu et nous les présentant en pratique comme une fonction « ordinaire ». Il poursuit avec un exemple de calcul paresseux, segmenté par étapes. Ensuite, il remplace une fonction calculant les nombres de fibonacci dans un vector<int> par une fonction retournant le prochain nombre de fibonacci à chaque appel. Comme je le fais parfois en classe, il modélise d'abord ce calcul par un foncteur Stateful. Cela lui permet de mettre de l'avant que les types de retour des coroutines jouent un grand rôle dans ce que ces fonctions peuvent faire.

Andreas Weis explique que ce qui transforme une fonction en coroutine n'est pas sa signature mais bien les mots co_await, co_yield et co_return (son générateur de nombres de fibonacci contient un co_yield).

Andreas Weis présente la plus petite coroutine possible :

ReturnType petite() {
    co_return;
 }

... puis il montre ce que ReturnType doit contenir. Le premier aspect clés est un type promise_type; comme avec les futures, la promesse est ce qui reste dans la coroutine, mais Andreas Weis indique que les coroutines et les fonctions async fonctionnement différemment. Pour implémenter un promise_type, il faut :

Sur cette base, avec un suspend_never pour initial_suspend(), il fait un petit Hello World

Andreas Weis explique que le type de retour d'une coroutine doit être Awaitable pour qu'on puisse faire co_await dessus. Un Awaitable doit exposer le prédicat await_ready(), la fonction void de signature await_suspend(coroutine_handle<promies_type>) et la fonction void de signature await_resume(). Il montre comment le type Awaitable qu'est suspend_always est implémenté

Andreas Weis décrit ensuite le coroutine_handle<promise_type> qui doit exposer void resume() const et void destroy() const, de même que des fonction promise() et to_promise() qui servent à des fins de conversions.

À mi-chemin, Andreas Weis procède pour expliquer le processus permettant de résumer l'exécution d'une coroutine. Il ajuste légèrement son exemple initial pour ce faire, ce qui est instructif (à noter pour la pédagogie). Ensuite, il élabore les relations entre coroutine, coroutine_handle, promise_type, type de retour, etc. Le schéma n'est pas quelque chose que je peux reproduire en temps réel alors faudra regarder ses diapos. Ses exemples sont bons, mais je vais vouloir les implémenter car je suspecte des erreurs mineures ici et là. Il montre entre autres comment sortir des données d'une coroutine, mais aussi comment y insérer des données (utile pour des fonctions comme celle que je présentais à CppNorth cet été?) et comment laisser sortir des valeurs distinctes à chaque appel.

Andreas Weis termine avec un exemple de transfert symétrique. Ça permet de basculer entre deux coroutines, ça s'implémente comme un Tail Call, et ça demande de passer en paramètre à un await_suspend() un coroutine_handle<promise> ce qui peut se faire un ajustant un type de retour.

Andreas Weis présente une série de Cheat Sheets en fin de diapos. Bonne idée!

Q : peut-on avoir des coroutines retournant void?

Andreas Weis : oui, mais l'appelant n'aura alors rien entre les mains. C'est flexible à ce point

Q : peut-on utiliser cela pour une approche Fire-and-Forget?

Andreas Weis : oui, et interagir avec un ordonnanceur

Q : le compilateur a-t-il besoin de savoir qu'un fichier objet déjà compilé utilise des coroutines?

Andreas Weis : non, seul le compilateur qui génère les coroutines doit avoir ce savoir

Q : que permettent initial_suspend() et final_suspend() que les constructeurs et le destructeur ne permettent pas?

Andreas Weis : on ne pourrait pas faire co_await sur un constructeur faute de type de retour

Q : comment savoir quoi faire lors du final_suspend()?

Andreas Weis : le plus simple est de faire suspend_always et détruire l'objet qui représente la promesse

C'était intéressant; je vais prendre des idées ici pour les exemples les plus simples et les intégrer à ma pédagogie, en le citant bien entendu.

Je ressentais un solide coup de fatigue pendant la présentation d'Andreas Weis, et j'ai réalisé ce matin (à mon grand désarroi) que ma vue semble baisser ce qui n'aide pas (effort oculaire). Je suis allé faire une petite sieste de 30 minutes à ma chambre, puis je suis redescendu vers la salle où Robert Leahy discutera d'un sujet sur lequel je travaille aussi depuis plusieurs années (je pense que ça va valoir la peine); démarrer la vie d'un objet représenté par un bloc de bytes brut est essentiel à tout ce qui touche à la sérialisation et à la réseautique en particulier. Sur mon chemin, je croise le toujours sympathique Thomas Besson, ancien du DDJV, qui est ici pour la première fois et en semble ravi. C'est toujours vraiment agréable de revoir les ancien(ne)s étudiant(e)s lors de ces événements; je suis chanceux, ça m'arrive assez régulièrement 🙂

Petite jasette avec le sympathique Ben Saks, qui est Chair du Embedded Track ici et que je croise souvent cat il participe à WG21 et à SG14 comme moi. J'en profite pour prendre des nouvelles de son illustre papa Dan Saks qui est l'une des personnes les plus intéressantes et les plus pertinentes que j'aie rencontré depuis que je fais les circuits internationaux; il se trouve que Dan Saks est en grande partie à la retraite maintenant, et qu'il concentre ses efforts publics sur des dossiers de politique américaine (nous en avions parlé lui et moi la dernière fois que nous avons eu l'occasion de bavarder).

Ben Saks présente le Embedded Track et se dit un peu ému de recommencer à parler en public après deux ans de confinement. Il fait un bon travail pour ce qui est de contextualiser le rôle de cette série de présentations. Il présente ensuite Robert Leahy.

Vidéo : à venir

Robert Leahy – Taking a Byte out of C++, Avoiding Punning by Starting Lifetimes

Robert Leahy commence en dissertant sur l'importance de la mémoire vive, et de bien comprendre ce qu'elle représente. Il mentionne que le modèle que nous appliquons pour la représenter et la comprendre brise parfois si on le pousse à ses limites. C'est une bonne entrée en matière : il part d'un struct fait de deux entiers, descend au niveau de la représentation en mémoire brute, puis regarde les diverses représentations que l'on peut inférer spéculativement à partir de cette représentation fondamentale. Il montre comment les types que nous imposons pour raisonner brisent en présence d'aliasing (parce que les compilateurs raisonnent sur la sémantique du code à partir de suppositions). Le type punning tenté par sa présentation brise (comportement indéfini).

Robert Leahy montre ensuite qu'on peut tricher d'autres manières, passant un uint32_t& à titre de struct { uint32_t, uint32_t } par exemple.

Robert Leahy y va ensuite avec un exemple qui utilise la valeur de retour de malloc() comme s'il s'agissait d'un int[]. Ça marche, heureusement, mais c'est brisé en C++ sur la base des règles (il n'y a pas d'objets à gauche de l'affectation), et change le int[] pour un string[]... ce qui recoupe directement mon cours de la fin de semaine passée 🙂 Il distingue les types triviaux des types non-triviaux. Il fait remarquer que même les types triviaux ont une durée de vie, et qu'il faut continuer de réfléchir.

Robert Leahy mentionne que C++ 20 introduit les types « implicit lifetime » (p. ex. : types qui ont un destructeur trivial et au moins un constructeur trivial). Certaines fonctions comme malloc() et memcpy() peuvent démarrer la vie d'un tel objet. Voir P0593 pour des détails. Cela rend l'exemple avec int[] correct (alors qu'il était techniquement incorrect avec C++ 17) et maintient le caractère indéfini de celui avec string[] (heureusement!). Avec des placement new, c'est toutefois correct (ici encore, heureusement!)

Note : Robert Leahy fait une excellente présentation aujourd'hui. C'est clair, c'est bien exprimé, c'est précis.

Robert Leahy montre ensuite des trucs qui sont désormais possibles et qui ne l'étaient pas auparavant (ça marchait... par accident ou par omission). Il écrit entre autres un bit_cast maison, fonctionnel mais non-constexpr à cause du memcpy() sous-jacent.

Robert Leahy montre quelques horreurs, puis explique l'intérêt de start_lifetime_as<T>(p) et de start_lifetime_as_array<T>(p,n). Bien joué! Il montre ensuite ce que cela a comme impact sur son code au boulot. Beau boulot encore, avec du code pertinent et compact qui met clairement de l'avant les enjeux (il utilise std::expected au passage).

Robert Leahy aborde ensuite l'importante question de la fin de la vie. Sur un même pointeur p, il utilise start_lifetime_as<T>(p) pour un type, puis plus tard cherche à le refaire sur le même objet mais avexc un autre T (le pointé est un type composite) ce qui peut détruire le premier objet. C'est la raison pour laquelle std::launder() est utile à ses yeux.

Robert Leahy propose une approche intéressante pour exprimer un concept qui couvre les cas où un usager aurait écrit certaines fonctions mais n'aurait pas correctement couvert les exigences de cette fonction, d'une manière à éviter les bris. C'est intéressant

Robert Leahy termine avec un résumé clair et bien fait. Il a clairement mis beaucoup de temps et d'effort dans cette présentation.

Q : que se passe-t-il si plusieurs types satisfont la même réduction?

Robert Leahy : le compilateur en pige une, mais laquelle... ce n'est pas spécifié

Q : on peut démarrer une vie implicite pour lire aussi. Est-ce un facteur? Je pense aux Memory-Mapped Files...

Robert Leahy : en offrant un constructeur trivial et un destructeur trivial, on informe le compilateur qu'on est prêt à vivre avec ça.

Staffan Tjernstrom : pourquoi as-tu posé un regard spécifiquement sur C++ 17 plutôt que ses prédécesseurs?

Robert Leahy : ma compréhension est que certains trucs ont été brisés en particulier par C++ 17

Q : comment deux types peuvent-ils être reliés l'un à l'autre pour fins de conversion?

Robert Leahy explique brièvement les règles

Vittorio Romeo : y a-t-il un trait pour détecter si un type est sujet à une durée de vie implicite?

Robert Leahy : non, à ma connaissance. On peut en écrire un, mais le problème est qu'il faut au moins un constructeur trivial, peu importe lequel (c'est difficile à définir sans l'aide du compilateur)

Q : dans le code où on a un if pour éviter qu'un tableau de taille zéro soit construit, l'optimiseur peut-il supprimer le if?

Robert Leahy : je ne l'ai pas vérifié, mais c'est un cas très étrange et je ne sais pas si cette anomalie du traitement particulier d'une taille de zéro va demeurer dans le langage.

Q : quel est l'impact de start_lifetime_as<T> sur constexpr? Il y a un constexpr sous la couverture, non?

Robert Leahy : je ne sais pas si start_lifetime_as<T> est constexpr, mais bit_cast<T> l'est et a besoin de magie de la part du compilateur

Q : que fait-on si on a un constructeur générique qui pourrait être trivial selon le type du paramètre?

Robert Leahy : je ne sais pas 🙂

Oh, que c'était bien ça. Bon travail Robert Leahy!

Je pars à la recherche de café, j'en trouve 🙂 puis je salue quelques ami(e)s (dont Nevin Liber, qui m'a préparé un chic chandail il y a un bout de temps, mais j'ai manqué deux rencontres in vivo du WG21 et il y a eu la COVID; je lui ai dit qu'on ne se verra pas à Kona en novembre mais que je vais essayer d'être au New Jersey en février). sur le chemin du retour vers la présentation de mon copain Klaus Iglberger. On parle d'une présentation de la série Back to Basics et je connais (très) bien le sujet, mais Klaus Iglberger est un très bon présentateur (et un bon auteur; achetez ses livres!) alors je compte plus prendre des notes sur la manière de présenter le sujet (et sur certaines intuitions de grande valeur, car il se peut qu'il y en ait quelques-unes).

Vidéo : à venir

Klaus Iglberger – Back to Basics, Value Semantics

Klaus Iglberger commence par un voyage dans le temps, où il présente la thèse de doctorat de Bjarne Stroustrup... écrite en Simula. Bjarne Stroustrup a découvert C en allant travailler chez AT&T Bell Laboratories, puis a développé C with Classes qui est devenu plus tard C++. Sa manière de voir le code a influencé le monde, et a teinté le livre sur les Design Patterns écrit par le Gang of Four (GoF). Klaus Iglberger fait remarquer que la plupart des schémas de conception exprimés dans ce livre le sont à l'aide d'héritage...

Klaus Iglberger prend d'abord un exemple qu'il aime bien, soit le schéma de conception Visiteur implémenté « à l'ancienne » avec des interfaces et des méthodes virtuelles. C'est un exemple que je connais bien (il est tiré de son livre); Klaus Iglberger revisite le problème pour transformer ses Shape* en une entité qui se comporte comme une valeur plutôt que comme une indirection. Il montre que passer par variant est avantageux à plusieurs égards (en particulier, c'est moins intrusif).

Klaus Iglberger a un style décontracté et amusant. La salle semble prendre plaisir à la présentation 🙂 Il aborde la question de la vitesse d'exécution avec des données qu'il fait promettre les gens de prendre comme illustratives.

Après cet exemple, Klaus Iglberger revient sur les aspects positifs de la sémantique de valeur, qui est son sujet aujourd'hui. En gros, ça apporte du bonheur. Par la suite, il montre que dans plusieurs cas, adopter une sémantique de référence peut mener à des surprises, même en situation const (la référence peut être const alors que le référé peut ne pas l'être). Il utilise span<int> const sur un vector<int> à titre de démonstration. Il montre même un cas de comportement indéfini en changeant le contenu d'un vector<int> auquel un span<int> const référait.

Klaus Iglberger montre ensuite comment il peut être dangereux d'utiliser des références avec des algorithmes, surtout quand on parle de références sur des éléments du subtrat qu'on modifie! Il tire ensuite des exemples de la bibliothèque standard (optional, expected, function, les conteneurs standards, etc.) qui mettent en valeur l'intérêt de la sémantique de valeurs. Une copie y est une copie, et const veut dire const. Il aborde le cas d'une fonction to_int() et son traitement d'erreurs (ça ressemble à mon division_entiere() classique)

Klaus Iglberger insiste : préférez la sémantique de valeur à la sémantique de référence. Vous serez plus heureuse et vous serez plus heureux.

Q : tu n'as pas parlé de la consommation de mémoire. Qu'en est-il?

Klaus Iglberger : vrai, mais ça ne fait pas de réelle différence. En fait, la différence est que tu n'as plus à t'en préoccuper! En plus, la contiguïté en mémoire est meilleure!

Q : l'héritage permet un ensemble ouvert de types, pas variant

Klaus Iglberger : vrai. Toutefois, dans le cas d'un Visiteur, ce n'est pas vrai qu'on peut ajouter des types sans douleur, même avec la forme classique

Q : ne peut-on pas faire la même chose avec du code générique?

Klaus Iglberger : oui, mais les exemples que j'ai utilisés étaient tous du polymorphisme dynamique, pas statique.

Q : comment tester avec du Mocking?

Klaus Iglberger : c'est habituellement abordé par voie d'héritage, vrai, mais ce nest pas exclu ici. Tu peux le faire avec le schéma de conception Stratégie et je montrerai dans une autre présentation vendredi comment y arriver

C'était divertissant 🙂

Je croise Thomas Besson qui était à lâ même présentation que moi et semble aussi avoir apprécié. Timur Doumler et moi bavardons un peu à propos de la rencontre de SG14 mercredi après-midi. Je croise Michael Wong qui s'en va vers la salle où se donnera sa présentation et on confirme qu'on va régler les derniers détails par courriel ce soir (on co-Chair la chose ensemble). Maged Michael arrive peu de temps après.

Le goûter est agréable : croustilles chaudes maison, petits bâtons de pretzels, mini pogos sans bâtons, trempettes.

Je me dirige ensuite vers la présentation de Michael Wong.

Vidéo : à venir

Michael Wong, Maged Michael, Paul McKenney – Concurrency TS 2 Use Cases and Future Directions

Michael Wong commence la présentation et nous informe que Paul McKenney est à Dublin et participera à distance.

Michael Wong commence par présenter l'évolution du Concurrency TS 2. Il dit ne plus être un grand fan de l'approche passant par des TS, après avoir été l'un des individus l'ayant soutenue initialement. Les Hazard Pointers devraient faire partie de C++ 26 et permettre de réaliser de la Deferred Reclamation (c'est un thème des RCU, des Snapshots (P0561), des clôtures asymétriques (P1202)...). Michael Wong parle de cette approche comme un mélange entre l'incertitude de Heisenberg et le chat de Schrödinger. Oh boy...

Michael Wong présente l'idée de synchronisation par procrastination. On échange de la certirude pour de la vitesse et de l'échelonnabilité. Ça a des applications dans la programmation sans verrou. Ça va trop vite pour prendre des notes, mais c'est une bonne présentation sur le sujet. La diapo 12 en particulier est instructive.

Michael Wong explique SNAPSHOT, qui se veut une interface RAII pour fins de Deferred Reclamation, puis les clôtures asymétriques (pour que le chemin commun et le chemin moins commun aient des caractéristiques différentes, ce qui peut accélérer certaines opérations). Enfin, il explique comment utiliser raisonnablement les outils de la Concurrency TS 2. Il parle aussi de l'intégration de ces nouveaux outils avec les coroutines.

Maged Michael poursuit. Il parle de trucs avec les Hazard Pointers étant donné l'interface prévue. Il résume ce que sont des Hazard Pointers : ils servent à protéger l'accès à des objets accédés à travers un pointeur Single-Writer, Multiple Readers (SWMR). En gros : si un Hazard Pointer pointe sur un objet avant son retrait, alors l'objet ne sera pas réclamé tant que le Hazard Pointer demeurera inchangé. C'est rapide et échelonnable, et ça protège un objet à la fois (ce qui les distingue de RCU par exemple).

Maged Michael présente ensuite les aspects essentiels de l'interface de std::hazard_pointer. C'est une approche intrusive : les types protégeables devront dériver de std::hazard_pointer_obj_base. La sémantique de mouvement est inhabituelle, il faudra que je l'étudie de plus près.

Maged Michael présente les fonctions try_protect(), protect() et reset_protection() qui constituent l'essentiel de l'interface de ce type. Il poursuit avec trois cas d'utilisation, soit protéger un objet sur une longue période; ce qu'il nomme le Hand-Over-Hand Traversal (par exemple, traversée concurrente d'une liste chaînée en protégeant deux noeuds à la fois); et l'itération (les Hazard Pointers peuvent permettre d'exprimer des itérateurs sur des conteneurs concurrents, ce qui n'est pas banal!). Ça ressemble à une gestion collaborative et concurrente de la durée de vie des pointés.

Maged Michael finit en disant qu'après 2026, il vise ajouter de la fonctionnalité aux Hazard Pointers (il y a un chemin de tracé!).

Paul McKenney parle sans qu'on ne puisse le voir, et Maged Michael change les diapos pour lui. Il présente RCU graphiquement. On perd le son occasionnellement, ce qui est un peu triste car c'est un sujet complexe... Maged Michael prend le relais (bien malgré lui!)

Maged Michael explique que plusieurs trucs sont possibles, et que l'objectif était de parler de RCU-Mediated Phased State Change au sens où on peut avoir des périodes dans l'exécution d'un programme où il est essentiel d'être très rapide et d'autres où il faut y aller avec plus de délicatesse (on peut représenter cela par un atomic<bool>). Il note au passage que même si rcu_synchronize() est un noop conceptuel, c'est tout de même une barrière de synchronisation au sens où elle bloque les réordonnancements et permet d'utiliser des atomiques relaxées.

Staffan Tjernstrom : du point de vue de la bibliothèque Folly, est-ce que TS 2 est proche ou loin de ce qu'on essaie de standardiser?

Maged Michael : la version Folly est un sur-ensemble de ce qui sera standardisé.

Beau travail dans des conditions hostiles. C'est le genre d'outils qu'il faudra apprivoiser... On joue avec des notions profondes et fondamentales avec des trucs comme ça.

Je dis un petit bonjour à mon amoureuse Za de même qu'à deux de mes enfants, Viktor et Ludo, puis je passe brièvement à ma chambre avant d'aller au Students' Dinner auquel Daniel Hanson m'a demandé de participer. Les bénévoles nous apportent un petit repas bien sympathique (du poulet frit, des légumes, de la salade; c'était très correct, bien convivial) et on bavarde pour le plaisir. J'ai passé une bonne partie de mon repas avec Max Sun, un étudiant canadien que j'avais aussi croisé à CppNorth cet été, et avec Christian (le nom de famille m'échappe), un sympathique personnage arrivé d'Allemagne et qui rève d'être impliqué dans des projets qui touchent à l'espace. Outre Daniel Hanson et moi-même, d'autres enseignants étaient présents (Hartmut Kaiser, qui a amené quelques-un(e)s de ses étudiant(e)s gradué(e)s au colloque – il semble très apprécié! – de même que les incontournables Walter Brown et Bjarne Stroustrup).

Je passe reprendre mon ordinateur puis je vais m'installer dans la salle de bal pour le dernier événement de cette grosse journée.

Vidéo : à venir

Committee Fireside Chat

Les membres du comité qui sont annoncés à titre de participants ce soir sont Herb Sutter, Bjarne Stroustrup, Daisy Hollman, Daniela Engert, David Sankel, Inbal Levi, Michael Wong, Nina Ranns, Pablo Halpern et Timur Doumler. Jon Kalb assure l'animation initiale, mais passe le relais à Herb Sutter pour l'animation.

Herb Sutter explique qu'il y a beaucoup de diversité sur la scène (il y a beaucoup de membres du comité ici!) car le souhait est de montrer que le comité n'est pas un bloc homogène. Il demande aux gens de dire pourquoi ils sont sur le comité.

Bjarne Stroustrup dit y être depuis les débuts en 1989. Il dit être un fan de la stabilité

Timur Doumler dit y être depuis 2016 et être actif, surtout dans EWG. Il s'intéresse aux systèmes à basse-latence et aux trucs qui lui semblent manquer de cohérence

Daniela Engert dit souhaiter polir les aspects plus tranchants du langage et s'intéresser aux modules

David Sankel dit être sur le comité depuis une dizaine d'années. Il s'intéresse à EWG et à LEWG, en particulier aux enjeux de Pattern Matching et de réflexivité statique

Daisy Hollman dit travailler... sur beaucoup de choses. En particulier, les exécuteurs et mdspan

Inbal Levy dit être impliquée dans SG9 et LEWG. Elle s'intéresse au design du langage et aux enjeux d'interfaces ou de lisibilité

Michael Wong dit être sur le comité depuis 2000 environ, et y être pour changer C++... mais c'est C++ qui l'a changé! Il a fait beaucoup de choses (les annotations, les littéraux maison, le modèle mémoire, etc.). Ces jours-ci, c'est la sécurité qui l'intéresse surtout.

Pablo Halpern dit être sur le comité depuis 2005 informellement, formellement un an ou deux après. Il est un des concepteurs des allocateurs pmr et donne beaucoup dans le parallélisme

Nina Ranns dit être sur le comité depuis 2013 environ et être une spécialiste des virgules 🙂 Elle s'implique surtout dans CWG et est actuellement secrétaire du comité

Herb Sutter a des questions soumises en ligne, alors il en posera à l'occasion

Q : que pensez-vous que C++ pourrait apprendre d'autres langages?

Daisy Hollman : le mot en C... Carbon? Rust, peut-être

Daniela Engert : je me souviens avoir travaillé avec un compilateur COBOL et avoir eu d'excellents messages d'erreurs

Bjarne Stroustrup : plusieurs langages ont d'excellentes infrastructures d'outillage. L'existence de macros nous nuit beaucoup en ce sens. Il faut éviter d'inclure un mécanisme à la fois; les mécanismes sont souvent interdépendants

Timur Doumler : on a des enjeux de compatibilité d'ABI et il est difficile de briser l'ABI en C++. D'autres langages l'ont plus facile en ce sens

Bjarne Stroustrup : on ne contrôle pas les ABI, ils appartiennent aux propriétaires des plateformes

Inbal Levi : C++ est un langage complexe. De meilleurs outils, de meilleurs messages d'erreurs sont deux choses qui seraient les bienvenues

Q : quand j'entretiens du code, j'aime bien supprimer plus de lignes que j'en ajoute. Qu'aimeriez-vous supprimer du standard?

David Sankel : dans tout gros système, ce qui est le plus difficile à supprimer est ce qui est en-dessous, ce qui soutient le reste. C++ est très près des fondations des systèmes. On y arrive malgré tout (p. ex. : auto_ptr), mais on sait que de gros bris empêcheraient des tas de gens de nous suivre. Nous évoluons en mettant en place de meilleures abstractions

Nina Ranns : on essaie de garder le langage aussi petit que possible. On a épuré certaines subtilités structurelles, des traits qui devenaient redondants, etc. On essaie de déplacer des spécifications vers de la programmation générative

Bjarne Stroustrup : la dépréciation est un chemin envisageable mais échoue pour l'essentiel du temps. Chaque fois qu'on veut enlever quelque chose, des milliers de gens en dépendent et ça coûte des milliards. On ne peut pas briser le langage; si les vendeurs de plateformes le voulaient, on pourrait briser l'ABI. On peut toutefois simplifier l'utilisation du langage

Daisy Hollman : j'ai deux propositions de dépréciation, soit la capture par défaut de this et l'usage de la virgule entre [] ce qui ouvre des avenues intéressantes. La dépréciation partielle de volatile a beaucoup de bon

Q : il est difficile de suivre les discussions du comité par listes de diffusion, et les archives sont un peu opaques. Comment pourrait-on mieux comprendre pour améliorer les outils?

David Sankel : le comité est une petite communauté multigénérationnelle alors que les technologies de communication changent sans arrêt. La pandémie me semble nous avoir montré des pistes de modernisation des pratiques

Bjarne Stroustrup : ISO est un mécanisme de prise de décision. Il est possible de s'impliquer et de participer au processus de décision. Malgré des faiblesses, c'est un réel mécanisme par lequel nous votons et progressons. Je ne suis pas convaincu qu'ajouter des milliers de voteurs améliorerait le modèle

Pablo Halpern : malgré sa taille, ce comité est spectaculairement fonctionnel. On peut bien sûr s'améliorer; cela dit, nous ne sommes pas une compagnie, alors nous prenons nos décisions sur d'autres bases que d'autres langages et nous n'avons pas le budget d'autres langages (nous avons un emploi de jour!)

Nina Ranns : tel que Pablo vient de le dire, nous sommes toutes et tous des bénévoles. Il ne faut pas l'oublier

Inbal Levi : selon moi, C++ n'est pas qu'un standard, c'est aussi plusieurs compilateurs, des outils, des gens...

Herb Sutter : une question à distance. Le langage évolue rapidement et son évolution est difficile à suivre. Est-ce que ça préoccupe le comité?

Michael Wong : on a cette question régulièrement, mais le fait est que vous n'avez pas à connaître l'entièreté de C++. Le langage couvre un large spectre technologique et une variété de domaines d'application

Daisy Hollman : il n'existe pas de sous-ensemble satisfaisant du langage pour tous les domaines d'application, et les machines deviennent de plus en plus complexes. Je pense que les modules vont nous aider à encadrer la complexité selon moi, même si je les connais peu, et le fait que je puisse les apprécier sans bien les comprendre indique que l'on n'a pas à tout comprendre

Bjarne Stroustrup : on peut simplifier l'utilisation du langage, mais pas le langage. Mon approche est les Core Guidelines, qui peuvent selon moi faciliter la bonne utilisation de C++. C++ est un langage généraliste avec des objectifs ambitieux

(je dois quitter pour préparer ma propre présentation, mais vous pourrez voir le reste sur Internet sous peu)

Je suis revenu à ma chambre travailler un peu sur ma propre présentation parce que le temps file...

Jour 2 13 septembre

Debout à 5 h du matin comme tous les jours, mais je suis fatigué et c'est plus dur de se lever ce matin. Beaucoup de travail à faire... Douche, petite jasette avec mon amoureuse Za prise avec des cas de diarrhée féline de son côté (j'aimerais être là pour t'aider mon amour), puis au boulot.

Une fois dans la salle, je vois un présentateur (Jonathan Gopel) tester la technique pour sa présentation de ... 14 h cet après-midi. Il y a de quoi le féliciter : mieux vaut régler la technique d'avance (et ennuis techniques il y avait)!

Marshal Clow et Dietmar Kuhl viennent s'asseoir avec moi. On jase un peu (surtout avec Marshal, qui arrive plus tôt; très chic type)

Vidéo : à venir

Roth Michaels – Case Study, Purging Undefined Behavior and Intel Assumptions in a Legacy Codebase

Roth Michaels semble enthousiaste et dit avoir trop d'anecdotes à raconter pour le temps à sa disposition 🙂 Il fait une chic blague avec un bout de code indéfini mais dans lequel il manque un ';' et met en relief que les messages d'erreurs s'améliorent, alors la vie embellit!

Roth Michaels va insister sur le caractère historique du code; le langage s'améliore, mais on est pris à entretenir ce qui existe, et parfois pour longtemps.

Roth Michaels va présenter un survol du comportement indéfini, puis rapporter des bogues intéressants détectés dans leur codebase. Il va aborder la question des changements à la culture d'entreprise requis pour combattre le comportement indéfini

Roth Michaels distingue UB, Implementation-Defined Behavior, Unspecified Behavior, IFNDR et toutes ces chouettes choses... Il recommande de ne pas écrire de code contenant du comportement indéfini (!). Il cite les textes de Chris Lattner et de John Regehr sur le sujet (de bons textes tous les deux)

Roth Michaels poursuite avec plusieurs exemples (qui ressemblent à ceux que j'ai présentés en classe il y a quelques jours), puis y va avec des exemples de son codebase qui dépendent de suppositions quant au modèle d'exécution de diverses plateformes... et qui se sont propagées à d'autres plateformes avec le temps, car le matériel se diversifie beaucoup

Roth Michaels explique sa démarche : activer tous les avertissements (sauf ceux de déprécation), traiter les avertissements comme des erreurs, essayer d'intégrer de l'analyse statique (pas nécessairement trivial car leur code utilise plusieurs modules tiers partis qui déclenchent les Sanitizers et masquent leur propre code)...

Roth Michaels poursuit avec des histoires de guerre : un bogue qui est survenu après une mise à jour automatique de XCode (certaines formes étaient déformées dans leur interface personne / machine)... Ils ont utilisé C-reduce et tout leur code est disparu, alors il y avait du UB de leur côté! Il souligne que si vous pensez avoir trouvé un bogue de compilateur... c'est probablement un bogue de votre côté (chez eux, c'était un problème de durée de vie avec un objet prenant et conservant l'adresse d'une temporaire transitoire)

Roth Michaels mentionne avec utilisé clang-format sur le code qui change pour le mettre en relief durant les revues de code. Il aborde ensuite la question d'objets utilisés mais incomplètement initialisés (ça n'arrivait jamais avant, mais les pratiques ont changé et... ils font parfois de la compression et déclarent des objets par défaut, donc incomplètement initialisés)

Roth Michaels parle d'un cas où le code brisait de manière non-déterministe à la compilation sans avoir été changé. Ils ont utilisé un Sanitizer pour traver le problème jusqu'à un Memory Pool... qui ne gérait pas l'alignement correctement, bogue masqué parce que, par accident, tout était de taille 8 par le passé

Roth Michaels aborde ensuite les enjeux de changement de culture. Il a fallu faire peur aux gens qui ne croyaient pas qu'il y avait un problème! Ils ont mis en place une règle qui indiquait qu'il est interdit de générer du code contenant un comportement indéfini ou de l'invoquer. Il a aussi fallu expliquer aux gens ce qu'est du UB! Il dit que les revues de code portent maintenant plus attention au UB, ce qui est déjà un gain

Roth Michaels discute des changements aux outils dont elles / ils se servent. Les avertissements de déprécation sont désormais des erreurs dans le nouveau code; les Sanitizers et clang-tidy (pour de l'analyse statique) font partie des outils de tous les jours; ils peuvent donc mettre graduellement à la retraite des fonctions remplacées par de meilleures alternatives sans changer le code existant. Il utilisent désormais ASan et UBsan; il recommande de rouler le code avec ces outils activés pour toutes les versions de test du logiciel. Il se trouve que les Sanitizers trouvent plusieurs bogues d'alignement, en particulier dans du code qui utilise reinterpret_cast

Roth Michaels relate que quand Apple a quitté les processeurs Intel, leurs ajustements de pratiques et d'outils ont porté fruit. Ils roulent maintenant Thread Sanitizer (TSan) manuellement, et semble que ça ait donné de bons résultats

Roth Michaels dit qu'il a une histoire sur les dangers de const_cast, qui aurait changé le sens du silence dans leur logiciel...

Q : quel outil de CI utilisez-vous pour provoquer des erreurs de déprécation et les traiter différemment?

Roth Michaels : les outils comme clang-tidy peuvent s'appliquer à certaines lignes seulement, On fait un diff sur les fichiers avant d'appeler clang-tidy, essentiellement

Q : tu disais avoir écrit du UB délibérément... As-tu rencontré des cas de UB que tu ne parvenais pas à supprimer tout en maintenant le comportement attendu?

Roth Michaels : je suis chanceux : non. Mais j'ai entendu des histoires... J'ai un cas de ralentissement en migrant de volatile à atomic, après quoi on a utilisé des atomiques relaxées, mais on a eu beaucoup de difficulté à bien les utiliser

Q : comptez-vous remplacer memcpy() par std::bit_cast?

Roth Michaels : oui, dans bien des cas. C'est pas toujours possible...

C'était divertissant. Va falloir que je lui demande son histoire de const_cast 🙂 Je pars vers la salle de bal pour remplir mon café et prendre ma place pour le Keynote de Daniela Engert. Sur mon (long!) chemin, en plus du café, il y a des bagels, des fruits et du yogourt... et de la bonne humeur!

Je m'attends à une présentation intéressante sur les modules. Il y a probablement un lien d'ailleurs avec un blogue par l'équipe de Visual Studio ce matin à propos du passage du codebase de Microsoft Office aux modules (le timing de la publication semble le suggérer, en tout cas!)

Vidéo : https://www.youtube.com/watch?v=yUIFdL3D0Vk&feature=youtu.be

Daniela Engert – Contemporary C++ in Action

Daniela Engert se présente, de même que son profil d'ingénieur électrique. Elle relate des conversation avec des gens qui expriment des « faits » comme « le comité est trop rapide », « le comité est trop lent », « le langage est mort »...

Daniela Engert s'est proposée de faire une application à partir de rien, incluant tous les mécanismes qu'elle n'avait jamais utilisé par le passé. Cela inclut les mécanismes de C++ 23 à sa disposition.

Daniela Engert essaie de définir « contemporary »... et en arrive à tout ce qui est à notre disposition depuis C++ 11. Et le « in action » mène à une démonstration concrète. Elle dit que cette démo inclut la collecte de données, la réseautique, une variété de plateformes matérielles...

Daniela Engert décrit ensuite les spécifications à partir desquelles elle a travaillé. Elle a construit une application client / serveur avec affichage graphique et transfert de trames vidéo. Elle a utilisé quelques bibliothèques comme ASIO, libav, SDL, et deux fonctions « maison » de son entreprise pour le traitement de texte UTF-8. Il se trouve que libav et SDL sont des bibliothèques C... Alors elle a enrobé le code déplaisant dans des types valeurs. À partir de concepts, elle en arrive à des propriétés plus saines pour le code qu'elle manipule

Daniela Engert présente le code de son décodeur vidéo (c'est joli, mais je ne note pas tout; vous regarderez la vidéo). On note au passage des champs de bits dont la taille dépend de valeurs calculées à la compilation, des Designated Initializers pour clarifier l'initialisation d'agrégats complexes, le recours à <filesystem> pour obtenir les fichiers disponibles, un parcours infini de fichiers dans un dossier qui se remplit et se vide continuellement (du Streaming), le recours à des Views et à des Ranges, des coroutines, une fonction consteval pour générer une λ qui vérifiera ultérieurement si un nom de fichier comprendra une extension... Daniela Engert met en valeur le fait que passer par des types valeurs simplifie radicalement le modèle de programmation

Daniela Engert : if you want to go fast, you need to proceed slow. Pour avoir du succès, faut avoir un plan, une méthodologie...

Daniela Engert explique son approche à à réseautique, exprimée par une composition d'opérations (je vais vouloir réexaminer cela avec les diapos). Elle mentionne que les Awaitables sont hautement configurables, et donc encore pleins de pièges en ce moment. Son code devient très élégant, dû à C++ 20 et encore plus avec C++ 23 dû à std::expected

Daniela Engert dit qu'une fois la réseautique en place, elle a mis ses mains dans les exécuteurs... P0443... mais qu'elle n'aura pas à en parler car ASIO peut s'exécuter à un plus haut niveau et profiter des contextes d'exécution... Elle a simplement ajouté un service d'arrêt de services prenant en paramètre un std::stop_token

Daniela Engert épluche le code étape par étape. C'est intéressant, mais ça ne se prend pas bien en note. Je vois des liens avec mon code doctoral; il y a des idées comme ça qui deviennent inévitables...

Daniela Engert les mécanismes clés sont selon elle generator, ranges, views, span, expected, concepts, requires, coroutines, structured bindings, stop_token et cie, des types valeurs, des types forts, des λ (entre autres des λ constexpr), et il m'en manque quelques-unes... Daniela Engert dit qu'un élément important est la capacité de composer le code source à partir de modules. Elle décrit la structure de ces composants. Cela lui a permis entre autres d'utilise Boost sans que cela ne se propage partout. Utiliser SDL a impliqué d'exporter des macros... qu'elle a transformé en entités de langage exportables pour ce faire. Elle rapporte des gains de temps de compilation extrêmement significatifs (inclure tous les en-êtes standards prend 2103ms environ, et faire la même chose avec un module demande 32ms).

Daniela Engert lance ensuite sa démo (Michael Caisse fait une apparition surprise 🙂). Elle compile l'application en mode Release devant nous. Elle semble avoir un bogue... (ça semble préparé 🙂). Il lui manque une ligne de code, qu'elle ajoute, puis elle recompile et exécute. C'est une jolie démo 🙂

Daniela Engert donne ses conclusions : le C++ contemporain est simple, concis, sécuritaire, composable (côté fonctionnel et côté code source), et surtout, c'est agréable! Elle remercie les membres du comité pour avoir réalisé cela, et remercie Hartmut Kaiser qui a changé sa vision personnelle du code en 2015. Elle pense que import std; va changer la vie de bien des gens. Elle remercie Stephan T. Lavavej, de même que Bjarne Stroustrup et Gabriel Dos Reis, et offre un gros merci à Chris Kohloff car elle a fait de petits miracles avec ASIO.

Q : combien de temps t'a-t-il fallu pour construire cette démo?

Daniela Engert : j'avais dix semaine au total, avec environ une heure par jour en moyenne car je procrastine...

Q : et le processus de développement?

Daniela Engert : ce fut assez simple; le débogueur tient tout à fait la route

Bjarne Stroustrup : merci. C'est beau de voir tous ces composants de C++ 20 et C++ 23 opérer ensemble. Cette intégration est difficile à atteindre. Merci au comité!

Q : tu as un Watchdog. Comment ça fonctionne?

Daniela Engert : explique la technique, mais c'est simple quand on connaît stop_source

Q : comment as-tu fait de ASIO un module?

Daniela Engert : ce fut assez simple. Faut se débarrasser des trucs non-exportables, comme les entités statiques (tu enlèves static 🙂) et t'es en voiture. Les modules ne sont compilés qu'une fois de toute manière. Pour le moment, seul MSVC peut compiler le code de ce projet cependant, et ASIO pousse le compilateur à ses limites

Q : tu as des cas où tu as ou OU logique entre deux opérations asynchrones sur lesquelles tu attends. Comment est-ce que ça fonctionne?

Daniela Engert : c'est la beauté de ce modèle, la complexité disparaît sous l'implémentation de l'opérateur

Q : bel exemple de ce que C++ permet de faire aisément et joliment aujourd'hui. Comment pourrait-on comparer ce que tu as fait avec un équivalent dans un autre langage?

Daniela Engert : dans ma compagnie, on n'utilise que C++ alors je ne sais que répondre à ceci

Belle démo, mais c'est le genre de présentation qui se savourera mieux avec les diapos pour bien voir les sources et les trucs qui y sont mis en application. C'était pas du tout ce à quoi je m'attendais 🙂

Je suis allé à ma chambre préparer des trucs pour la rencontre de SG14 demain, puis un travail pratique (pas tout à fait prêt) pour certain(e)s de mes étudiant(e)s. Ensuite, je suis parti à la recherche de café, mais les réchauds ne sont pas encore revenus. En marchant vers la salle de la prochaine présentation, j'ai croisé Lawrence Boyle (un de mes étudiants de la fin de semaine, et qui a suivi un autre de mes cours l'an passé) et nous avons bavardé recherche un certain temps. C'est une personne fort agréable. Par la suite, alors que je me préparais à la rencontre, Bjarne Stroustrup est passé bavarder un peu; il a pris sa retraite de Morgan Stanley quelques mois puis est redevenu professeur pour Columbia University, ce qui lui permet de travailler sur le langage encore. Il semble en pleine forme 🙂

Phil Ratzloff est seul sur la scène; je crois comprendre qu'Andrew Lumsdaine participera mais à distance. Plusieurs trucs intéressants en même temps, mais je viens ici pour me préparer en vue de demain où Phil Ratzloff présentera sa bibliothèque devant SG14 et SG19.

Vidéo : à venir

Phil Ratzloff & Andrew Lumsdaine – Graph Algorithms and Data Structures in C++ 20

Phil Ratzloff se présente et dit qu'Andrew Lumsdaine a fait une présentation semblable l'an passé, mais qu'ils n'avaient pas beaucoup de code à présenter; la situation semble différente cette fois. Ce qu'ils visent est un type std::graph, basé sur P1709 (il suggère d'attendre la publication de P1709r2 car il y a eu des changements importants depuis r1).

Phil Ratzloff commence par retracer un historique des bibliothèques de graphes en C++. Si on se fie sur le schéma proposé, ils semblent viser une adoption pour C++ 26.

Phil Ratzloff décrit ensuite ce qu'est un graphe (définition classique). Il montre une esquisse plus près du code et décrit des enjeux conflictuels entre la gestion de l'espace et celle de la vitesse. Il existe plusieurs manières de créer un graphe, et laquelle choisir dépend du contexte et des besoins. Le design sur la table ne couvre pas les graphes bi-partites ou n-partites, et ne couvre pas non plus les hypergraphes.

Phil Ratzloff fait une liste des défis de conception. Rendre leur utilisation simple et agréable est un bel enjeu. Dans son exemple, la notation pour traverser un Range of Ranges est jolie. Il implémente l'algrorithme de Dijkstra de manière élégante, en passant d'un poids égal pour tous les chemins à un poids par chemin en faisant un tout petit ajustement. Je note qu'il applique requires sur un alias défini par using!

Phil Ratzloff poursuit avec les vues et leur définition. Ensuite, il montre un algorithme de traversée en largeur, presque pareille à celui de traversée en profondeur

Phil Ratzloff dit que toutes les fonctions de visite sont des fonctions globales et sont des points de personnalisation. Il parle du csr_graph, qui représente une matrice éparse. Il montre quelques-unes des fonctions clés associées a ce type. L'API de ce type devrait être de la même forme que celles des autres types de graphes, incluant quelques traits et quelques concpts

Phil Ratzloff aborde ensuite la question des autres types de graphes, et discute de CPO et de tag-invoke... Ils ont une version qui utilise variant et quelques variantes  (!) structurées autrement

Phil Ratzloff explique que la proposition sur la table n'inclut pas encore d'algorithmes parallèles, mais est intéressé à en savoir plus si les gens expérimentent aec la bibliothèque (https://github.com/stdgraph/graph-v2). Andrew Lumsdaine mentionne que les algos parallèles sur des graphes sont souvent très différents de leur contrepartie séquentielle

Q : offrez-vous la stabilité des pointeurs?

Phil Ratzloff : la taille des graphes CSR est fixe. Pour certains autres on peut envisager quelque chose de plus dynamique

(j'ai manqué une question)

Q : avez-vous pensé à permettre un contrôle sur la topologie du graphe pour permettre certaines ajustements quand c'est possible?

Andrew Lumsdaine : on a fait quelques expérimentations avec une autre bibliothèque, NWGraph. Ça fait effectivement une grosse différence parfois.

Q : le graphe sera un Range of Ranges. Quel est l'externe et quel est l'interne? Aussi, comment gérez-vous les exceptions?

Phil Ratzloff : le Range of Ranges est la liste d'adjacence. Pour le reste, nous ne faisons rien de spécial pour les exceptions

Bjarne Stroustrup : donnez-moi un exemple de concepts, et quel bénéfice attendez-vous du recours aux Niebloids?

Phil Ratzloff : c'est la manière que je connais pour personnaliser les opérations

(j'ai manqué une question)

Le contenu est intéressant, mais le présentateur est un peu monocorde et je m'endors... Le café est enfin arrivé alors je fais le plein, et je croise Daniel Hanson avec lequel je planifie un rendez-vous ce soir avant les Lightning Talks (il veut qu'on discute de son livre-à-venir sur lequel j'ai fait une révision technique cet été). Je me dirige ensuite vers la présentation de Timur Doumler à laquelle je pensais initialement assister à 14 h, mais il y a conflit avec celle de Nevin Liber maintenant et je vais voir Timur Doumler plus tard cette semaine alors ce sera Nevin Liber cette fois 🙂

Vidéo : à venir

Nevin Liber – MDSPAN, A Deep Dive Spanning C++, Kokkos & SYCL

Nevin Liber commence par présenter la forme d'un mdspan avec dimensions statiques ou dynamiques. Ça va un peu vite pour prendre des notes, mais il fait pas mal le tour. En gros, on parle d'un type non-owning comme string_view ou span et il y a des outils pour accéder au substrat selon diverses modalités. L'accès multidimensionnel se fait à partir de l'opérateur [] avec virgules de C++ 23, donc mat[i,j,k]

Nevin Liber retrace l'histoire de mdspan à une proposition (N3851) de Herb Sutter et d'autres, basée sur AMP à l'époque. Il explique les embûches qui ont ralenti l'adoption de ce type (ça a pris huit ans) et comment le type a changé au fil des propositions. Ça se nommait array_view à l'époque et les extents étaient fixes

Nevin Liber relate le Array TS débuté en 2013 à Chicago. Il fait la nomenclature des diverses sortes de tableaux proposées. Un truc nommé dynarray<T> semblait prometteur mais plusieurs trucs acrochaient... Un truc nommé array_ref est devenu span et un truc nommé string_ref est devenu string_view. Le Arrays TS est mort en 2016 à Jacksonville.

Nevin Liber relate ensuite les propositions qui sont venues pour améliorer la proposition de tableau multidimensionnel. Pendant un temps, le array_view unidimensionnel et le array_view multidimensionnel n'étaient encore qu'un seul et même type. Il continue le fil de l'histoire, mais c'est plus amusant si vous regardez la présentation. On voit toutefois comment les préoccupations ont été traitées, et comment le design d'une bête comme celle-là peut prendre forme au fil des années

Nevin Liber présente ses excuses; c'est sa faute si typename std::span<T>::size_type est non-signé. Il regrette un peu...

Nevin Liber fait une parenthèse à propos des contrats et de ce qui ralentit leur adoption, car certains ont ralenti mdspan en attente des contrats.

Nevin Liber explique que le nom mdspan est apparu en 2017, en conformité avec span. La version de 2018 se rapprochait, dans sa forme, de la version finale

Nevin Liber fait un petit laïus sur l'importance de CTAD dans l'utilisabilité de mdspan. La raison est que mdspan a beaucoup de paramètres de templates (la diapo 115 montre bien la démarche complexe de déduction)

Nevin Liber poursuit avec les liens entre SYCL et mdspan. L'idée est que maintenant que mdspan est bel et bien un type vocabulaire, on veut l'utiliser! De leur côté, Kokkos refactorisent leur View interne autour de mdspan.

Nevin Liber indique qu'un mdarray est sur la table. Celui-ci serait owning. Nevin Liber préférerait qu'on en fasse un adaptateur. Il y a cependant des enjeux : on ne peut pas le créer par défaut, et si on le construit sur un vector<T> alors que le vector<T> devient Moved-From, que fait on?

Nevin Liber dit que malgré toutes les tergiversations, mdspan est un très bon type et il est content des résultats 🙂

Q : peux-tu donner un exemple d'une fonction qui change la taille d'un mdarray?

Nevin Liber non. Il n'y a pas de resize()

Bjarne Stroustrup : puis-je avoir un mdspan vide avec un indice signé?

Nevin Liber : oui!

Bjarne Stroustrup : yes!!!

Q : pourquoi est-ce important d'avoir un entier signé en tant qu'index?

Nevin Liber : c'est plus rapide!

J'ai une fringale alors je vais remplir mon café et prendre une collation (crudités, hummus, tranches de pommes). Je bavarde avec Bjarne Stroustrup à propos de sa perception de la présentation sur ce qui pourrait être std::graph. En revenant de la zone où se trouve le petit goûter, je croise Matteusz Pusz qui semble en excellente forme! Je m'installe ensuite pour la présentation de Pablo Halpern.

Vidéo : à venir

Pablo Halpern – Embracing Trailing Return Types and `auto` Return *Safely*

Pablo Halpern commence par une blague, et explique qu'il discutera de l'intérêt d'utiliser auto f() -> int { return 3; } plutôt que auto f() { return 3; }

Pablo Halpern présente bien sûr le livre dont est tiré cette présentation, livre dont il est co-auteur, et la méthodologie qui y est appliquée

Pablo Halpern y va d'un tour d'horizon de la syntaxe (il a fait le tour alors c'est parfois utile). auto f()() const & -> int const & final; fait pas mal le tour. Le fait que l'on soit, après le nom de la fonction, dans le contexte de la fonction permet un allègement syntaxique occasionnel dans le cas des fonctions membres, mais le principal avantage est de pouvoir utiliser le nom des paramètres dans une expression comme celles utilisant decltype

Pablo Halpern poursuit en expliquant comment decltype fonctionne... et pourquoi on veut parfois ajouter remove_cvref_t sur le résultat 🙂 Il clarifie aussi la différence entre decltype(x) et decltype((x)) quand x est un nom d'objet (ajouter les parenthèses donne une référence)

Pablo Halpern explique que le type se lit souvent plus simplement avec cette notation. Par exemple, si on retourne un pointeur de fonction, c'est beaucoup plus lisible (ça rappelle la distinction entre typedef et using...). On se répète parfois un peu pour cette raison

Pablo Halpern travaille par la suite sur la distinction entre les types de retour déduits et les types de retour spécifiés. Ne pas spécifier le type de retour équivaut à spécifier -> auto (belle remarque). Il fait ensuite le tour de la question du recours à auto en général... Je vois un exemple chouette

 struct C { int v; }; C c;
 auto f0() { return c; }
 // ...
 auto f6() -> auto(&)() { return f0; } // <-- ceci
 auto C::* f7() {return &C::v; } // <-- ceci

Pablo Halpern présente les opérateurs de conversion de forme operator auto() ou operator auto&() const 🙂 Les règles de surcharge sont particulières si on a plusieurs variantes de operator auto() (même nom, mais on peut les distinguer par leur signature). Il explique pourquoi (dans les phases de compilation, la signature et le corps ne sont pas évalués durant la même étape). Les déclarations doivent correspondre (auto f(); ne peut être suivi par int f();), On ne peut pas retourner une initializer_list avec auto (c'est une temporaire)et on ne peut pas retourner virtual auto, pas plus qu'on ne peut déclarer un vector<auto>

Pablo Halpern fait un petit tour par decltype(auto). Note : on ne peut pas décoder un decltype(auto) (p. ex. : const decltype(auto) ou decltype(auto)& sont illégaux)

Pablo Halpern présente un exemple avec des types compliqués (p. ex. : un système d'unités fait d'un triplet <DistanceExp, MassExp, TimeExp>). Il montre que diviser des unités génère des types de retour douloureux.

Pablo Halpern y va avec les critiques. Il met de l'avant que l'interface dépend de l'implémentation avec cette approche, alors qu'on préfère habituellement l'inverse. Aussi, de cette manière, modifier l'implémentation peut modifier l'interface et forcer à tout recompiler. On peut souffrir sur le plan de la lisibilité dans certains cas si on néglige de spécifier le type de retour

Pablo Halpern donne ensuite ses recommandations, mais c'est pas mal ce que je dis en classe. Il a un cas subtil (diapos 46-47) avec SFINAE qui embarque ou pas selon la présence ou nom d'une spécification de type de retour.

Q : je n'ai pas compris le tour de passe-passe entre int et ... dans le cas SFINAE

Pablo Halpern : int est un meilleur match que ... mais c'est une technique avancée

Vittorio Romeo : est-ce que c'est moins dangereux si on enrichit auto avec un concept?

Pablo Halpern : je pense que oui

Q : à la diapo 22, si on remplace long par T, peut-on créer un T par défaut?

Pablo Halpern : return T() ou return T{}

Q : peut-on utiliser decltype(auto) de manière sécuritaire pour éviter une violation du principe DRY

Pablo Halpern : decltype(auto) peut retourner une valeur si l'expression est une valeur, auto&& retournera toujours une référence. Ça peut briser ton code si t'es pas prudent. Pour le reste, on s'en reparle

Je prends quelques moments pour parler à Za, Vitkor et Ludo, puis je prépare un travail pratique pour mes étudiant(e)s du Collège. Ensuite, je vais à la rencontre de Daniel Hanson pour lui donner un coup de pouce dans la rédaction de son livre. Éventuellement, les Lightning Talks débutent.

Vidéo : voir ci-dessous

Lightning Talks

Marshal Clow joue les maîtres de cérémonie. On a droit à (note : je suis dans le fond de la salle alors j'ai peut-être mal lu certains noms et certains titres) :

De retour à ma chambre, j'ai mangé un peu (salade, croustilles, bière – c'est cher!) et j'ai travaillé un peu, mais j'ai beaucoup de fatigue oculaire cette semaine et j'ai fini par devoir m'arrêter.

Jour 3 14 septembre

Debout tôt, je parle avec Za et Ludo (les voyages devaient être difficiles avant Internet!), puis douche et rasage avant de reprendre le collier.

J'ai peu de tâches distinctes aujourd'hui, mais je serai très occupé car je serai co-Chair de la rencontre conjointe du SG14 et du SG19 cet après-midi. On nous demande de tester le fonctionnement hybride pour faire un rapport à Herb Sutter en vue de la rencontre hybride du WG14 en novembre. Aussi, dans cette rencontre, outre le volet protocolaire habituel, nous avons deux gros dossiers soit les travaux sur un éventuel std::graph dont j'ai eu un aperçu hier, et mon propre document cumulant les demandes de gens de l'industrie du jeu, qu'on étudie collectivement pour le transformer en de multiples propositions. J'ai d'ailleurs retouché (légèrement) ce document hier pour l'envoyer au groupe, question d'aider tout le monde à se préparer.

J'ai croisé Robert Leahy en marchant vers la salle de bal, ce qui m'a permis de lui dire en personne combien j'avais aimé sa prestation de lundi. Je suis aussi allé parler à Karen Krueger (note organisatrice adorée) pour m'assurer que mon transport vers la maison vendredi ést bel et bien organisé. On a convenu elle et moi que l'horaire prévu était un peu serré (je préfère ne pas être à la dernière minute à l'aéroport) et on a devancé le transport d'une heure. C'est vraiment très agréable de travailler avec elle.

Choses intéressante : je ne connais pas les deux présentateurs que je verrai ce matin, alors ce sera une découverte...

Vidéo : à venir

Alex Dathskovsky – From Templates to Concepts The Amazing Journey of Metaprogramming

Alex Dathskovsky dit que tout son code aujourd'hui compilera, et qu'il compte rendre les templates moins épeurants. Il compte démontrer que le débogage est moins laborieux qu'il n'y paraît

Alex Dathskovsky commence avec les function templates pour montrer que template <class T> void print(T) ne peut être spécialisé par template <class T> void print(T*) (c'est pas comme ça que les templates sur les fonctions opèrent). Il montre aussi que l'ordre de déclaration fait une différence (déclarer print(T) puis print(T*) puis print(double*) ne donne pas le même résultat que déclarer print(T) puis print(double*) puis print(T*))

Alex Dathskovsky poursuit avec les class templates, mais rapidement, puis examine les traits, en  commençant par <type_traits>, pour ensuite utiliser des traits à titre de contraintes. Il y va d'abord avec du tag dispatching (il passe son étiquette comme premier paramètre, étrange...), puis montre les suffixes _t et _v. Un survol de if constexpr suit, de même qu'un premier concept (auto, exprimé par auto& et auto*) puis il utilise const pointer auto pour éviter une ambiguïté

Alex Dathskovsky aborde SFINAE et utilise un exemple avec ... comme dernier recours. Il se fait un trait naïf is_container<T> en testant pour la présence du type interne et public typename T::iterator, mais indique que c'est pas l'idée du siècle

Alex Dathskovsky présente ensuite enable_if, ce qui est un drôle de choix après avoir mentionné les concepts. Par la suite, il introduit les templates variadiques, et poursuit avec void_t. Il présente void_t comme un enable_if plus propre, mais c'est pas vraiment le même cas d'utilisation...

Alex Dathskovsky revisite son trait is_container à l'aide de void_t. La démarche est pas mal, mais il y a des trucs invérifiables sur sa diapo. Il prend une démarche par étapes avec plusieurs alias intermédiaires

Alex Dathskovsky revisite son trait is_container à l'aide de concepts et de requires. Il rapporte de très jolis messages d'erreurs (mais je vois une faute sur une de ses diapos; personne n'est parfait!). Il a toutefois un cas amusant de constexpr bool comp(auto bi, not_equable<decltype(bi)> auto ei) { return true; }

Alex Dathskovsky donne des exemples d'utilisation. C'est des choix pas bêtes, mais c'est parfois un peu Sloppy (préconditions non-spécifiées). J'aime bien la qualité des messages d'erreurs rapportés cela dit

Alex Dathskovsky fait un plaidoyer pour les concepts et montre que le code est de plus en plus joli, de plus en plus simple avec chaque version de C++

Q : peut-on créer un concept sur un alias, p. ex. : que typename T::value_type est std::integral?

Alex Dathskovsky : oui, bien sûr. Une fois mal pris, tu peux construire ton propre concept à partir de traits

Daisy Hollman : je pense que tu confonds la métaprogrammation et la programmation générique; aussi, tu dis aimer enable_if et void_t, mais as-tu regardé les deux en termes des messages d'erreurs à l'aide d'un compilateur récent?

Alex Dathskovsky : je pense que void_t demande moins de code à écrire; c'est vrai que les messages d'erreurs se sont améliorés pour enable_if et void_t aussi, je suis d'accord

Q : quelle est la taille du code machine généré avec des concepts ou avec void_t?

Alex Dathskovsky : les temps de compilation sont un peu plus longs avec les concepts, mais je ne sais pas pour le code machine.

Q : est-ce que les concepts éliminent le besoin de enable_if, void_t et SFINAE?

Alex Dathskovsky : bien sûr que non, du moins pas pour le moment

Ok, pas parfait mais un effort honnête, de bonnes idées et assez bien livré (le présentateur aime visiblement son sujet).

Le goûter du matin est fait de fruits, incluant de petites brochettes de melons et de fraises, de café et de petites pâtisseries format bouchée. C'est agréable. J'aime bien quand on garde ça léger pour les goûters, et cette semaine ce fut principalement « santé » dans l'ensemble. Je croise Richard Powell (chic type rencontré à Toronto cet été) qui bavarde avec Jason Turner et j'essaie de l'hypnotiser pour qu'il participe à SG14 cet après-midi. Je ne sais pas si ça va fonctionner mais il y serait à sa place.

Je travaille avec mes collègues des cours IFT339 (allo Vincent Ducharme!) et 420KBB (allo Marc Beaulne, Fabien Howison, Sébastien Richer et Philippe Simard!) sur la gestion de l'horaire et des travaux des étudiant(e)s pendant la pause

Jon Kalb présente ensuite Erik Rainey comme un spécialiste des robots volants (des drones!) chez Amazon 🙂

Vidéo : https://youtu.be/QwDUJYLCpxo

Erik Rainey – Using C++14 in an Embedded "Superloop" Firmware

Erik Rainey se présente et décrit les caractéristiques physiques de l'appareil sur lequel il travaille, avec une petite vidéo en prime. Les robots d'Amazon (Amazon Prime Air) sont progammés en C++ 14.

Erik Rainey nous parlera de l'environnement et du firmware; des restrictions de C++ 14 dans un contexte de systèmes embarqués; et de recommandations pour programmer sur un système embarqué avec C++ 14.

Erik Rainey explique ce qu'est le firmware. Il dit que c'est un terme pour lequel les définitions varient selon les personnes, et pour lequel la complexité varie aussi beaucoup (il en va de même pour les contraintes d'espace, de temps, de latence, etc.). Habituellement (pas toujours), on parle de :

Erik Rainey parle de plusieurs sortes de firmware :

Erik Rainey décrit le matériel comme étant typiquement un microcontrôleur, pas de MMU, peu de protection mémoire, petite (mais rapide) SRAM, typiquement moins de 1MB, souvent une petite mémoire Flash (moins de 4MB), peut-être des nombres à virgule flottante (ou pas), et une horloge cadencée dans les MHz. Souvent, un Hardware Watchdog pour réduire les risques de bris. Interagit souvent avec des bus lents et de bas niveau. Démarre rapidement (moins d'une seconde), et doit s'exécuter sur une longue période sans problème (parfois des années). Souvent peu de courant. Peut avoir de la mémoire avec correction d'erreurs intégrée et injection d'erreurs pour fins de test.

Erik Rainey décrit le Super-loop comme une boucle for avec un seul contexte d'exécution, où les tâches sont visitées une à une par la boucle. Il n'y a pas de limite logicielle au temps d'exécution, mais il y a une limite matérielle. On ne connaît pas le temps de la prochaine exécution, et une opération bloquante peut paralyser le système. Pas de tâche idle, alors le processeur est toujours utilisé à 100% (il faut faire attention à la chaleur). On mesure normalement le min / max / avg d'une itération de la Super-loop et le min / max / avg pour chaque tâche dans le but de voir si on a un comportement délinquant

Erik Rainey on n'a pas de tas (de Heap), car l'appareil doit être radicalement robuste; le temps requis pour malloc() paralyserait la machine. Pas de mémoire virtuelle, de thread, de processus, d'ordonnanceur, de système de fichiers, d'exceptions... de modèle de l'usager, d'appels systèmes bloquants

Erik Rainey explique que l'objectif est la robustesse : on élimine des classes entières d'erreurs run-time (pas de fragmentation, de manque de mémoire, d'inversion de priorité, etc.) en essayant de se limiter aux erreurs compile-time. Moins de fonctionnalités, ça veut aussi dire moins d'endroits où quelque chose peut briser, et ça facilite la tâche de raisonner sur le système. C'est plus déterministe, plus répétable, plus facile à tester

Erik Rainey parle du comportement indéfini; l'approche prise pour la programmation réduit fortement les risques de comportement indéfini, surtout dans le noyau. En fait, dans un système critique, le comportement indéfini n'est pas une option, et s'il faut certifier le logiciel, ça fait partie du contrat

Erik Rainey explique qu'il reste beaucoup de trucs intéressants : le système de types de C++ demeure remarquable et permet l'écriture de code expressif, même quand on amène C++ jusqu'au métal. Il reste de petits bouts d'assembleur à écrire, mais peu. On a une pile d'exécution, parfois aussi une pile privlégiée; des appels systèmes (qui placent une barrière de protection devant un petit nombre de fonctions « dangereuses »); un vecteur d'interruptions; etc. et une bibliothèque stamdard adaptée (p. ex. : printf mais peut-être pas les codes de formatage pour les float)

Erik Rainey dit que les compilateurs sont de la variété "none", p. ex. : arm-none-eabi-g++, et des éditeurs de liens adaptés. Demander trop de mémoire statique fait en sorte que les programmes ne compilent pas (ceci s'applique à d'autres régions de mémoire aussi)

Erik Rainey dit éviter les interruptions le plus possible (ça en prend un peu, par exemple pour le moteur du drone, car c'est un TR). Conséquemment, la plupart des périphériques sont accédés par sondage. On tend à utiliser de la mémoire globale... car on n'a pas beaucoup d'alternatives 🙂 Au démarrage, partant du reset() à main(), on crée une pile (adresses hard-codées seulement, pas de globales à ce stade); on obtient CRT0 qui intialise les globales; on appelle les constructeurs globaux, puis on appelle main(). On doit savoir quad les constructeurs sont appelés si ces constructeurs sont, essentiellement, le système : qu'est-ce qui est disponible à ce stade? Peut-on faire des appels systèmes? Les interuptions sont-elles activées?

Erik Rainey décrit l'environnement de Build (on fait un seul binaire; tous les types sont connus à al compilation). On a beaucoup de files ou de files circulaires. On utilise des conteneurs qui permettent de contrôler le moment de construction des objets. On utilise des tuples maison pour rapporter les erreurs et les endroits où elles surviennent. Le pilote du bus utilise une file de transactions; les erreurs sont combinées au tampon circulaire pour arrêter le système si nécessaire

Erik Rainey explique que l'environnement d'exécution devient en quelque sorte un automate. C'est compréhensible et ça se teste bien. C'est toujours non-bloquant et concurrent, et il n'y a pratiquement jamais de récursivité

(je vais chercher du café rapidement; il parle de capteurs)

Erik Rainey dit qu'on n'utilise pas de boucle infinie, sauf celle du programme principal (un forever, ou for(;;)). On évite les pointeurs, préférant les références. Il note que l'adresse zéro est typiquement utilisée pour quelque chose d'utile! Les exceptions ne sont pas une option (incluant noexcept; étrange...), RTTI non plus, pas d'allocation dynamique (new / delete; malloc() / free()), pas de dynamic_cast. Cela complique le recours à la STL (pas de vector, de unique_ptr... de bind?). Il évite les allocateurs, même maison, car ils veulent supprimer l'idée-même d'allocation (il décrit une démarche pour accepter la disparition du tas)

Erik Rainey dit d'activer tous les avertissements et de les traiter comme des erreurs. Si on utilise des bibliothèques tiers-partis, faut être prudents. Quand les compilateurs ou les analyseurs statiques suggèrent des améliorations, portez attention. Faites des tests unitaires!

Erik Rainey suggère de ne pas réinventer les types primitifs. Il recommande d'utiliser <cstdint> et de se limiter à uintptr_t pour les adresses. On ne peut pas éviter les adresses, mais dans le code mieux vaut préférer les références chaque fois que c'est possible, même pour modéliser les périphériques. Utilises les namespace de C++, ça vaut la peine. Appliquez le principe DRY, utilisez des portées pour limiter la visibilité des noms. Organisez le code source avec rigueur.

Erik Rainey suggère aussi d'utiliser des interfaces strictes pour que les frontières entre les classes soient claires (il dit que le coût d'un appel polymorphique est souvent compensé par le design mieux structuré)... mais de garder le design simple (et d'éviter les diamants). Utiliser final est payant, et passe un message clair aux usagers (ceci est flexible, ceci ne l'est pas). RAII est essentiel dans un système embarqué, surtout quand on utilise placement new. Limitez inline aux fonctions les plus simples (la mémoire est une denrée limitée). Utilisez const le plus possible, mais sachez que le matériel est étrange et ne connaît pas const alors assurez-vous que les fonctions const n'aient vraiment pas d'effets de bord.

Erik Rainey rappelle que volatile est important dans ce type d'appareils, particulièrement pour les zones comme les Memory-Mapped Registers. Il utilise parfois les méthodes volatile en pratique. On peut utiliser mutable, mais seulement si c'est absolument nécessaire (p. ex. : collecter des métriques, mécanismes non-bloquants de type try-lock). Les atomiques sont un outil pertinent s'ils sont bien utilisés (c'est plein de pièges). Contrôler le moment de construction des objets est important, et il faut réfléchir à l'ordre de construction avec soin (note : il utilise void main(void) dans ses exemples...)

Erik Rainey recommande d'éviter le préprocesseur si possible, et de préférer les templates et constexpr. Les constructeurs constexpr sont une idée précieuse à ce niveau, et constexpr devrait être utilisé autant que possible. Évidemment, static_assert est un outil merveilleux pour ce genre de programmation. Il en va de même pour alignas, surtout pour ces types qui doivent comprendre le bus ou la Cache. Les énumérations fortes sont un gain net, les traits aussi. Il suggère d'utiliser =delete sur ce qui n'apporte pas de bonheur (un clin d'oeil à Marie Kondo?), et mentionne qu'appliquer le mouvement sur un périphérique, c'est non.

Erik Rainey suggère d'implémenter les opérateurs surchargés en groupes, et d'éviter ceux qui peuvent demander de la gestion de cas limites comme operator[]. Il dit que les littéraux maison sont pertinents mais suggère de les grouper dans un namespace. Il mentionne au passage que certains cadriciels de tests sont confus devant ce mécanisme. Il recommande l'initialisation avec accolades pour réduire les risques de narrowing. Il et favorable aux constructeurs explicit.

Erik Rainey explique ce qui ralentit la progression de C++ sur le firmware (il mentionne MSRA-202x et AUTOSAR qui ne couvrent pas C++ 17 encore). Quand on aura C++ 17, plusieurs trucs seront utiles comme [[deprcated]], if constexpr, variant, optional, [[fallthrough]]... et avec C++ 20, on attend les modules, consteval, les concepts, l'initialisation des champs de bits, etc.

Q : comment gères-tu les erreurs dans un constructeur?

Erik Rainey : on a le tuple pour les erreurs qui sont rapportées dans la boucle; pour les opérateurs et les constructeurs, on écrit là, mais on va parfois choisir de continuer l'exécution

Q : avec une petite pile, as-tu un avertissement quand tu as de la récursivité? Et sais-tu de combien de pile tu as besoin?

Erik Rainey : on a un mécanisme pour fixer la taille de la pile

Q : que fais-tu quand les tâches sont épuisées?

Erik Rainey : ça n'arrive pas, c'est un ensemble statique de tâches

Q : pourquoi pas C?

Erik Rainey : C++ a un meilleur système de types et est préférable pour un système critique

(je manque une question)

Q : que fais-tu quand une tâche précise est soumise à des contraintes de temps d'exécution?

Erik Rainey : c'est l'intérêt d'une Super-loop. On n'a jamais une garantie totale d'exécution, et on veut un système simple, alors on réagit si on détecte qu'elle ne démarre pas au bon moment

Q : pourquoi aurais-tu besoin d'un verrou avec un seul contexte d'exécution?

Erik Rainey : quand on doit faire plusieurs transactions Stateful à travers le bus

Q : pourquoi C++ plutôt que Rust si la sécurité est si importante?

Erik Rainey : ces langages espèrent que le système gère les problèmes pour eux, mais le matériel est très robuste, le registre n'a pas de types, et le code à ce niveau peut mener à des erreurs que le langage n'aidera pas à régler. Mieux vaut écrire du code correct. Ça n'enlève rien à Rust

Q : as-tu pensé utiliser des coroutines?

Erik Rainey : on y réfléchit, mais je ne suis pas sûr que fonctionnerait (risque d'allocation). Ne pas bien voir ou comprendre ce qui se passe impacte la confiance...

Q : utilises-tu ds algorithmes?

Erik Rainey : parfois, mais quand on certifie le logiciel ils nous demandent de les enlever...

Intéressant, mais ça laisse des questions en suspens... Je me demande s'il viendra à SG14 tantôt...

Je m'installe pour un gros après-midi...

Vidéo : il n'y en aura pas (c'est une rencontre ISO)

SG14

J'ai co-animé, avec Michael Wong et Staffan Tjernström (avec l'aide inestimable d'Inbal Levi) une rencontre étrange de SG14 (avec un peu de SG19) où plusieurs participant(e)s étaient techniquement des invité(e)s (il y a des règles chez ISO sur la présence de non-membres, et elles ont été resserrées récemment). J'étais très actif alors je n'ai pas pris de notes ici (de toute manière, les rencontres ISO doivent être anonymisées).

En gros, j'ai pris en charge la partie « développement de jeux » de la rencontre en poursuivant les efforts débutés il y a plusieurs mois déjà sur un gros document colligeant les besoins de programmeuses et de programmeurs de jeux vidéo; Timur Doumler a présenté une de ses propositions sur la table qui rendrait légale en C++ la lecture de bytes individuels d'un int par exemple (c'est légal en C mais illégal en C++, même si ça fonctionne en pratique, car les deux langages ont des définitions distinctes de ce qu'est un pointeur), et Phil Ratzloff a présenté une partie de ce qu'il souhaiterait voir devenir std::graph.

Ce fut une rencontre productive, avec des pistes intéressantes à explorer dans chaque cas et (pour moi spécifiquement) plusieurs individus qui souhaitent collaborer sur tel ou tel aspect de la massive proposition sur la table. Ce fut une rencontre étrange, en retour, car elle se tenait en mode hybride du fait que nous avions le mandat de roder la mécanique avant la rencontre du WG21 en novembre.

Ça a pris tout l'après-midi...

Pour le reste de la soirée, outre une petite (mais dispendieuse) bouchée, j'ai parlé à mon amoureuse Za, aux plus jeunes Vitkor et Ludo, aux chics beaux-parents Jocelyn et Danielle (une jasette de groupe), et j'ai travaillé sur ma présentation de demain matin.

Jour 4 15 septembre

Derniers préparatifs pour la présentation de ce matin. Je paie quelques factures car c'est le matin de la paie (aussi entré, aussitôt sorti... Hé la la).

Il y aura un débat des chefs en vue des élections québecoises ce soir à la télévision, mais je vais le manquer car je serai au Meet the Presenters Banquet (un chic privilège : un bon repas et l'occasion de bavarder avec les gens qui participent à l'événement et souhaitent parler avec nous; ça fait plusieurs fois que je fais cela et c'est toujours agréable)

Vidéo : à venir

Patrice Roy – Reviewing Beginners' Code

J'ai fait de mon mieux, mais ça a semblé bien reçu.

J'ai bavardé avec plusieurs personnes par la suite, et l'ambiance semblait bonne. Tant mieux! Semble qu'il y ait une faute sur une des diapos (un 'e' de trop ou un 'e' manquant) alors je vais la corriger avant de publier les diapos (je ne sais pas où elle est!). Note : il y avait deux fautes, corrigées depuis (un "intresting" auquel il manquait un 'e', et un "companys" qui était en fait un "company" avec CTRL+S mal pressé sur le clavier pour sauvegarder). J'ai aussi reçu de gentils courriels de gens qui assistaient par Internet.

Je suis content que ce soit fait, et j'ai hâte de voir la présentation de Timur Doumler. Jon Kalb nous annonce qu'il nous offre à toutes et à tous le dîner aujourd'hui (cool!) et demain (re-cool!).

Vidéo : https://www.youtube.com/watch?v=eD-ceG-oByA

Timur Doumler – How C++23 Changes the Way We Write Code

Timur Doumler se dit honoré d'offrir un Keynote; c'est à CppCon qu'il a donné sa première conférence à vie il y a sept ans! Il décrit son profil, incluant la bibliothèque audio pour laquelle il est connu.

Timur Doumler commence en disant que depuis juillet, C++ 23 est Feature-Complete. Quand il a présenté une première conférence sur C++ 20 dans le passé, il avait fait un survol de plusieurs petites choses. Cette fois, il souhaite prendre un autre angle. Plutôt que d'examiner des petits aspects individuellement, il souhaite prendre une approche plus holistique (plus près de son autre présentation sur C++ 20 qui examinait en priorité les quatre plus gros aspects de ce standard). Bien sûr, C++ 23 est plus petit (!) que le gigantesque C++ 20...

Timur Doumler passe par la page décrivant le support de C++ par version et par compilateur. Il montre qu'il y a quand même beaucoup de nouveaux aspects pour le langage, et encore plus pour la bibliothèque. Il fera donc une sélection tout à fait subjective : il retire les Defect Reports, il enlève les ajustements (ajouter un constructeur, ajouter noexcept, ce genre de truc), il y a des tas de trucs qui touchent spécifiquement aux Ranges, qui sont une bête en soi... et il y a des tas de trucs qui touchent au support d'Unicode (SG16 travaille vraiment fort, en particulier Corentin Jabot; Timur Doumler recommande son Lightining Talk nommé TEXT!). Enfin, il retire plusieurs petits trucs qui simplifient la vie comme des améliorations à CTAD ou la non-obligation de mettre de parenthèses à certaines λ qui en avaient besoin pour des raisons historiques, et il retire les améliorations aux mécanismes existants. Après cela, ce qui reste tient sur une seule diapo.

Timur Doumler épure encore un peu plus : les trucs qui recoupent le préprocesseur, les trucs qui touchent à la compatibilité avec C, les littéraux std::size_t, les nombres à virgule flottante avec taille enchâssée dans le nom du type, [[assume]] (même si c'est de lui), et quelques outils spécialisés de la bibliothèque standard qui seront très utiles, mais pour de petits segments de la communauté. Il lui reste une dizaine de mécanismes, dont les modules pour la bibliothèque standard et les générateurs qui complètent les coroutines, de même que std::stacktrace, std::flat_map, std::flat_set, et std::move_only_function. Reste quatre trucs : Deducing this, <expected>, std::mdspan et le améliorations à <format>

Timur Doumler commence par Deducing this, le plus important changement au Core Language, qui règle (selon Bjarne Stroustrup) deux problèmes d'un seul coup... Timur Doumler dit que selon lui, ça en règle même trois! Il montre comment ce (vraiment brillant) changement au langage permet, en collaboration avec le Perfect Forwarding, de réduire drastiquement le nombre de surcharges de fonctions dans les cas où nous avons const, volatile, &, && en diverses combinaisons. Ça règle le problème de duplication du code source, le problème de la simplification de l'idiome CRTP et le problème des λ récursives pour lequel il prend un chic exemple de la présentation de Ben Dean l'an passé où il écrit un code de navigation d'arbre qui est franchement élégant.

Timur Doumler explique ensuite qu'avec std::expected, qui a été accepté suite à la douzième version de la proposition, on déplace le choix de la modalité du signalement d'une erreur du code appelé vers le code appelant, ce qui permet au code appelant de travailler en fonction de modalités qui lui conviennent. Il suit une démarche semblable à la mienne dans ma présentation de 2016 où j'utilisais std::optional<T> pour modéliser peut-être un T, mais avec la subtlité que std::expected<T,E> modélise soit un T, soit une erreur de type E. Il donne un bel exemple avec std::accumulate() où le problème, s'il y a lieu, se propage élégamment du code appelé vers le code appelant (mais je pense que sa proposition ne fonctionne pas car on perd la nature de l'erreur exprimée à travers une hiérarchie de classes problèmes dû au fait que l'on utilise une valeur (ça peut fonctionner avec un variant). Il montre aussi un mécanisme qui permet de faire quelque chose qui se rapproche des exceptions de Java avec variant et expected... si on y tient vraiment 🙂

Timur Doumler enchaîne avec mdspan. Il dit que c'est son préféré des quatre. Pour expliquer les raisons, il parle de son passé et de ses recherches doctorales en physique avec des données de grande taille exprimées en trois dimensions et plus... en Fortran. Il rappelle les facilités numériques de Fortran, et montre que Fortran faisait certains trucs (comme afficher un tableau!) dans les années '60 que C++ 23 nous permettra enfin de faire naturellement. Tout de même! Quand il est passé à C, ça a fait mal, disons... En C++, avant C++ 23, c'est plus joli, mais reste que c'est du code répétitif et perfectible dans bien des cas. Avec mdspan, c'est aussi joli qu'en Fortran. Ajoutez à cela que la notation tab[i,j,k] est maintenant supportée en C++, c'est franchement plus plaisant qu'auparavant. Timur Doumler fait remarquer que puisque mdspan est un type Non-Owning, on peut appliquer plusieurs perspectives sur un même substrat. Ajoutez à cela qu'il est possible d'avoir des dimensions statiques et des dimensions dynamiques et on obtient un type très polyvalent, très expressif. Il montre comment faire divers parcours d'un mdspan, incluant une courbe de Hilbert en deux dimensions, puis en trois dimensions.

Timur Doumler en arrive à std::print(). Simple, efficace, élégant, change comment on exprime "Hello World" 🙂 Il discute des irritants associés à std::cout traditionnellement, incluant le traitement du UTF-8 sur Windows. Il passe bien sûr par std::format() de C++ 20 pour expliquer la syntaxe. Il explique que std::print() fait la bonne chose, point. Enfin. Et il y a std::println() si vous préférez.

Q : à propos de std::expected, tu as soulevé qu'il est parfois utile d'avoir des exceptions. Y a-t-il des cas où les exceptions sont meilleures que std::expected?

Timur Doumler : elles rendent le code plus simple dans bien des cas; j'utilise les exception quand les contraintes du code ne sont pas critiques.

Q : tu as parlé des coûts des outils de <iostream>. Comment std::print() évite-t-il ces coûts?

Timur Doumler : je ne suis pas l'expert dans ce domaine, mais std::print() évite les flux de <iostream> et en-dessous.

Q : y a-t-il des conversions implcites entre std::span et std::mdspan?

Timur Doumler : (demande à Daisy Hollman, qui dit qu'on les a enlevées car elles étaient trop compliquées)

Q : quels sont les coûts de std::expected<T,E> en comparaison avec le retour d'un code d'erreur?

Timur Doumler : je ne les ai pas mesurées, mais tu retournes une paire à travers une interface différente...

Q : il me semble que std::expected<T,E> est intrusif au sens où ça se propage partout...

Timur Doumler : oui. Si tu veux que ça se propage, faut le faire

C'était du bon travail, clair et amusant.

Le dîner proposé était bon. Belle variété de légumes, salade, petites pommes de terre, un peu de poulet, un peu de poisson, de petits desserts sympathiques. Je me suis assis à une table où il se trouve que certaines des personnes avaient assisté à ma présentation du matin, et où Roth Michaels s'est joint à moi (il me disait quelque chose quand je suis allé voir sa présentation, mais pour une bonne raison : il était dans ma classe l'an passé!).

Je suis allé à ma chambre me repose une trentaine de minutes, j'ai parlé à mon amoureuse Za, puis je suis allé assister à la présentation de mon copain Jody Hagins

Vidéo : https://www.youtube.com/watch?v=Taf5eqUZAA0

Jody Hagins – Using Modern C++ to Revive an Old Design

Jody Hagins dit souhaiter parler de design. Il parle du Saint-Graal (forte cohésion, faible couplage, etc.) et mentionne un bon livre par James Coplien, et ajuste une de ses citations pour la rendre un peu plus large. Il montre au passage une petite bouteille de sauce Tabasco (je les aime aussi; il y en a partout ici) et dit qu'il a aimé l'idée que pour ajouter de la sauce à son burrito du matin, le fait d'ajouter une petit bouteille est un plus faible couplage à ses yeux que de réouvrir le burrito, mettre de la sauce et le refermer.

Jody Hagins discute de couplage (deux composants sont couplés si modifier l'un impacte l'autre) et de cohésion (une vocation par composant; tous les morceaux contribuent à l'implémentation). En C++, qui supporte plusieurs paradigmes de programmation, l'idée de composant recoupe plusieurs idées distinctes. Il donne des exemples, et ils sont amusants. Pour savoir si un changement impacte positivement ou négativement ces deux aspects, il suggère de se demander si écrire un test devient plus facile ou moins facile suite au changement. Selon lui, le bloc de code est l'unité qui crée le plus de couplage et le moins de cohésion.

Jody Hagins propose une démarche graphique pour visualiser les dépendances. Il montre une approche permettant de simplifier le schéma, ce qui ajoute des tests, puis glisse vers une technique qui remplace les tests dynamiques par des opérations réalisées à la compilation. Il parle ensuite de sa relation d'amour avec C++ et avec le code de niveau noyau 🙂 Il parle de sa jeunesse et de sa difficulté à comprendre l'affectation car il venait des mathématiques (on voit de belles photos de sa jeunesse; il est divertissant!).

Jody Hagins explique la démarche derrière le projet qui sous-tend sa présentation : une application locale qui devait devenir répartie. Il explique comment il a réussi à faire la transition sans changer une seule ligne de code : il a fait une bibliothèque qui supportait la même interface que celle des fonctions de communication inter-processus, a compilé le tout en une bibliothèque, et a refait l'édition des liens avec cette nouvelle bibliothèque 🙂 Il entre ensuite dans les détails de l'implémentation, et montre comment les interfaces homogènes aident à réduire le couplage

Jody Hagins explique que la fiabilité est rapidement devenue un requis. Il montre que dans les années '90, malgré les rumeurs que c'était une mauvaise idée, il avait du code C++ s'exécutant dans le noyau d'Unix. C'est un peu un plaidoyer pour la composition de fonctions ou les séquences d'appels de fonctions qu'il nous fait. Il nous explique ensuite pourquoi son système est peu connu (plusieurs raisons : pas pour Linux, roule dans le noyau, ce genre de truc).

Jody Hagins explique sa technique pour choisir les tâches à faire dans chaque étape à partir d'informations connues à la compilation (en gros, il utilise SFINAE sur le type de retour et ajuste les types des paquets triés en les annotant par des types étiquettes, que ce soit par voie d'ajout ou par voie de suppression).

Q : sur la diapo 16, le schéma n'est-il pas le schéma de conception Chained Responsibility?

Jody Hagins : pas vraiment, mais tu peux le voir comme ça si tu veux

Q : est-ce implémentable dans d'autres langages?

Jody Hagins : je ne sais pas. Je suis en amour avec C++

Q : qu'est-ce qui améliorerait ton design avec C++ 20?

Jody Hagins : les concepts!

Q : ton système est linéaire. As-tu des branchements?

Jody Hagins : oui, j'ai des multiplexeurs mais je n'avais pas le temps d'en parler ici

Q : est-ce comparable à des files de messages?

Jody Hagins : je ne passe pas les messages, je passe des types enrobés, et je peux procéder autrement que par copie si tel est le souhait

Q : diapo 69, peut-on lever une exception dans le code du noyau?

Jody Hagins : c'est probablement pas la 69. Je peux gérer une exception... au sens où ça va appeler std::terminate() car on est dans le noyau. En pratique, c'est un système de messagerie réactif

Bon travail cher ami! Je profite du fait qu'Ezra Chung, qui est bénévole ici, est assis tout près pour valider avec lui où je dois déposer les diapos de ma présentation du matin. Il a la gentillesse de m'aider,ce qui me sauve beaucoup de temps.

En marchant vers la présentation du toujours excellent Barry Revzin, je vois des Hoodie de CppCon. Je contacte mon amoureuse Za pour savoir si elle en veut un, mais elle rejette mon offre. J'ai le coeur brisé 🙂 Je croise ensuite Pablo Halpern et je lui pose une intéressante question qu'un étudiant m'a posé sur le comportement des ressources pmr:: mixtes, dont il est l'architecte. Il me donne une réponse très claire et je le remercie (j'ai communiqué la réponse à qui de droit depuis). Je croise ensuite Erik Rainey qui a donné le Keynote hier matin; j'aborde la question de noexcept dont il ne saisissait probablement pas vraiment les contours et je lui donne une piste (on verra ce qu'il en fera)... et j'arrive en retard à la présentation de Barry Revzin.

Vidéo : https://www.youtube.com/watch?v=EQELdyecZlU

Barry Revzin – The Surprising Complexity of Formatting Ranges

J'arrive en retard alors je ne prends pas les notes habituelles... C'est une excellente présentation, très claire et très pertinente, mais je n'en attendais pas moins de Barry Revzin. Les diapos seront précieuses! P2286 est la clé...

Super boulot de la part de Barry Revzin, vraiment. Ça allait beacoup trop vite pour prendre des notes mais les diapos étaient très bien faites et très complètes.

J'ai eu assez de café aujourd'hui alors je rapporte ma tasse à ma chambre et je reviens (ce qui prend dix minutes!). Je croise une des personnes présentes dans ma conférence de ce matin qui me pose quelques questions intéressantes, et me demande si j'ai des exemples comparant une correction (rétroaction sur le code) et le résultat attendu de la part d'un(e) étudiant(e); c'est une bonne idée, je vais peut-être faire quelques exemples si j'ai le temps un de ces quatre (oui, je sais...)

Je croise Rainer Grimm et on jase un peu. Le goûter est fait de chips de maïs, d'une salsa fraîche et d'un peu de pico de gallo. C'est très bon. Je retrouve ensuite ma place où Ezra Chung (qui partage la prise de courant avec moi depuis quelques jours 🙂 travaille sur un possible Lightning Talk pour ce soir. J'espère qu'il aura le temps, c'est un brillant personnage!

Vidéo : https://www.youtube.com/watch?v=l6Y9PqyK1Mc

Francesco Zoffoli – How to Use Dependency Injection to Write Maintainable Software

Francesco Zoffoli commence par expliquer ce qu'est une injection de dépendance. C'est une approche schématique, assez bien faite, qui met de l'avant l'intérêt d'avoir des raisonnements locaux sur la base d'interfaces. Il aborde la question du mode de passage de dépendances d'un composant à un autre (p. ex. : passer un objet par référence ou à travers un shared_ptr n'entraîne pas les mêmes dépendances). Il dit qu'une dépendance devrait imposer les requis nécessaires, et rien de plus, car il y a un coût à chaque dépendance. Il recommande de passer des références simples, pas des pointeurs intelligents, si c'est possible.

Francesco Zoffoli discute de types de dépendances : sur les données et sur les comportements. Pour les données, on préfère des entités en lecture seule pour éviter les cas d'action à distance. La données peut être constante ou changer au fil du temps; cela fait selon lui partie de l'interface. Il recommande le recours aux types valeurs avec des types structurés, explicites. Il prend l'exemple d'un vector : 5/5 pour la vitesse, 1/5 sur la liberté pour l'appelant. Avec un span, 5/5 pour la vitesse, 2/5 pour la liberté. Avec une entité polymorphique comme any_range, 1/5 pour la vitesse, 5/5  pour la liberté.

Francesco Zoffoli dit que les constantes sont l'idéal; si les données peuvent changer mais sont localement en lecture seule, il recommande d'être clair. Par exemple, utiliser un std::atomic_ref<const T>. Cela rend les tests triviaux, et découple le producteur du consommateur (on peut changer la source de données). Selon lui, le cas d'utilisation ici est de pousser (push) des données vers le composant; il recommande des comportements dans le cas des pull

Francesco Zoffoli dit que les comportements tendent à être des effets Stateful. Pour des actions qui demandent du polymorphisme dynamique, il suggère de passer des std::function ou d'autres outils du même acabit; pour du polymorphisme statique, il recommande invoke_result et invokable dans la signature du composant. Pour le recours à des hiérarchies de classe, il recommande des bases purement abstraites car les constructeurs (s'il y en a) seront exécutés lors des tests, quelque chose qu'il faut éviter selon lui. Il propose une démarche basée sur les concepts pour grouper des groupes de comportements.

Francesco Zoffoli parle du passage de dépendances, et recommande d'éviter les setters à tout prix. Ils peuvent mener à des cycles et créent des durées de vie confuses. Les constructeurs sont une bien meilleure solution à tout point de vue. Il examine ensuite quelques exemples de signatures qu'il estime intéressantes, plusieurs reposant sur une forme de composition de fonctions suppléées par l'appelant. Cela apporte beaucoup de flexibilité.

Francesco Zoffoli parle ensuite de fabriques, pour ne pas avoir à instancier explicitement des types précis. Il décrit une fabrique comme un moyen de créer une dépendance à partir de paramètres, et insiste sur l'importance de retourner une abstraction (en C++, ça peut être un concept, ce qui évite les coûts des interfaces classiques). Si un concept n'est pas une option, alors retourner un unique_ptr<T> T est une interface est une option. Une autre est de retourner un shared_ptr<T> (c'est pire, selon moi). Il en vient à retourner un truc qui contient deux niveaux de shared_ptr... et disons que je ne le suivrai pas là (il ne vit clairement pas dans le même monde de contraintes que moi!). Il propose une alternative qu'il nomme un HolderPtr.

Francesco Zoffoli aborde ensuite la question de l'abstraction des composants, pour abstraite un composant en tant qu'assemblage de sous-composants. Une fabrique est une option ici, un struct en est une autre. Cela donne la capacité d'exposer de multiples interfaces et donne une gestion de vie automatique, mais exclut le polymorphisme (selon lui) et introduit une dépendance envers un détail d'implémentation. Cette abstraction peut faciliter les tests en permettant de tester les détails d'implémentation séparément les uns des autres.

Francesco Zoffoli conclut avec un bref retour sur la présentation. Il dit avoir présenté des outils pour gérer la complexité et parle de chercher l'équilibre entre les différents enjeux.

Q : je vois des shared_ptr partout. Pourquoi? Ça coûte si cher...

Francesco Zoffoli : oui. Ça me semble être un choix sécuritaire, mais c'est vrai que c'est peut-être beaucoup

Q : tu crées un type qui prend une dépendance puis utilise cette dépendance; ceci n'ajoute-t-il pas de la complexité?

Francesco Zoffoli : j'étends la durée de vie des objets en leur donnant une maison

Q : et si on passait un type encapsulant plusieurs comportements plutôt qu'une function?

Francesco Zoffoli : en général, les références sont mieux car on ne veut pas prendre le contrôle de l'objet ou le construire alors préfère function_ref

Q : est-ce que les allocateurs sont une dépendance comme une autre? Je sais qu'il y a une proposition pour un allocateur de niveau langage...

Francesco Zoffoli : question intéressante. Je ne sais pas. Passer des allocateurs le long d'une chaîne est un cas d'utilisation valide.

Q : tu recommandes de passer des références, mais tu recommandes des entités immuables...

Francesco Zoffoli : oui, je veux des Immutable References idéalement

Pas mauvais, donc, mais je ne suis pas convaincu par l'approche et c'est parfois un peu confus. Je n'ai pas noté toutes les questions. J'ai l'impression qu'il a vouloir retravailler le tout pour le futur. Je suis ensuite allé parler à mon amoureuse Za quelques minutes et me préparer pour le banquet (j'ai mis des jeans, une chemise, des bas et des souliers pour la première fois de la semaine).

Aux abords du banquet, j'ai bavardé avec Jody Hagins (qui souhaite une annotation [[hot]] pour C++, qui ne serait pas la même chose que [[likely]] alors je lui ai demandé d'écrire une ébauche de proposition pour qu'on puisse voir si ça peut être intégré au document de souhaits de la part des artisanes et des artisans du monde du jeu vidéo) et Staffan Tjernström (qui, apparemment, va utiliser un peu de français dans son ouverture pour son Lightning Talk ce soir).

Vidéo : à venir

Meet the Presenters Banquet

Nous nous sommes dispersés dans la salle (il y a beaucoup de monde). L'organisation a placé des étiquettes « speaker » à divers endroits alors on se disperse, mais je me suis retrouvé avec le sympathique Staffan Tjernström malgré tout (qui n'est pas un présentateur cette semaine). L'autre présentateur à ma table était  Marc Grégoire. Nous avions avec nous quelques chouettes personnes avec qui nous avons bavardé pendant une heure trente environ.

Le service était excellent, la salade était très bonne. Le plat principal était correct (asperges, riz, un peu de poisson et un peu de poulet, quelques petites tomates et un coulis de crème), le dessert était très bon (sorte de crème caramel et pêches avec un petit croquant sucré et une framboise décorative), et le vin (du rouge pour moi) était très correct. Jon Kalb semblait d'excellente humeur alors je pense que l'événement fut un succès cette semaine.

Je suis ensuite allé reprendre mes aises brièvement, puis je me suis installé pour les derniers Lightning Talks de la semaine.

Vidéo : à venir

Lightning Talks

Marshal Clow joue le maître de cérémonie et le fait très bien. Nous avons quatorze présentation de prévues ce soir :

On a fini un peu tard, mais c'était amusant et ça donne des idées.

Je voulais corriger ce soir mais ce sera le dodo pour moi...

Jour 5 16 septembre

Dernier matin ici, alors je me prépare pour le Check-Out. Douche, rasage, petit bonjour à mon amoureuse Za (et à Miss Miou, un de nos félins). Je prépare mes bagages, je remplis mon formulaire ArriveCan (c'est vrai que c'est laborieux comme truc; il me semble que le processus mériterait d'être retravaillé), je m'assure que le transport soit à la bonne heure pour que je puisse partir en toute quiétude, etc. Je prends des photos de mes factures, je télécharge des travaux d'étudiant(e)s à corriger (si j'ai de l'alimentation électrique dans l'avion... et j'ai encore assez d'énergie, parce que j'ai accumulé beaucoup de fatigue cette semaine) et je cours après les retardataires (un classique).

Je procède au Check-Out, je marche vers la première présentation de ce matin, et je croise successivement Staffan Tjernström (que je félicite pour son Lightning Talk bien mené d'hier), Barry Revzin (qui a fait un super travail hier aussi et que je remercie), et le toujours sympathique Ben Deane (qui habite dans la région et profite du fait que le dernier jour est gratuit pour assister aux présentations de la journée!). J'ai aussi le plaisir de recevoir des compliments pour ma présentation d'hier, de la part de gens que je ne connais pas. Ça se prend bien! Je prends soin de remercier les bénévoles et les employés de l'hôtel; ce genre d'événement ne fonctionne rondement que quand on a une excellente équipe avec nous...

En attendant l'arrivée de Marshal Clow, je commence à faire un peu de correction car j'accumule du retard cette semaine...

Vidéo : à venir

Marshal Clow – Class Template Argument Deduction History, How to Use it, and How to Enable it for Your Classes

Marshal Clow se présente comme Inigo Montoya et demande de voir combien de doigts nous avons dans nos mains 🙂 Il se présente plus sérieusement (beau curriculum vitae, évidemment) par la suite

Marshal Clow il commence par expliquer ce qu'est CTAD, soit un mécanisme pour laisser le compilateur déduire des trucs qu'il devrait pouvoir déduire. C'est une étape dans une longue démarche de simplification du langage, une série d'étapes pour ne pas avoir à dire des choses dans le code qui ne sont pas nécessaires... ce qui nous évite de dire la mauvaise chose! Évidemment, ça fonctionne bien pour les tucs évidents, mais ça couvre beaucoup de cas!

Marshal Clow appuie son argument en donnant un exemple où on aurait dû écrire tous les types pour une fonction qui manipule un vecteur (un appel à std::find(std::begin(v), std::end(v), 3)) Sans aide, c'est un mur de texte. Avec paramètres par défaut (pour l'allocateur), c'est beaucoup mieux. Avec déduction des paramètres de templates à partir des paramètres d'une fonction, c'est encore mieux. Avec CTAD, c'est tout propre

Marshal Clow aborde ensuite la question de ce que CTAD fait. Il donne des exemples avec vector et avec pair, qui sont toujours porteurs. Il enchaîne avec la question du « comment » et introduit les guides de déduction implicites de même que les guides de déduction explicites. Il présente la syntaxe des guides de déduction. Il dit que règle générale, pour un guide de déduction, on ne se préoccupe pas de &, de const& ou de && car on ne fait que guider la déduction vers un type

Q : est-ce important pour un(e) débutant(e) de comprendre les problèmes résolus par auto et par CTAD?

Marshal Clow : non, mais c'est pratique par contre

Q : est-ce que la syntaxe des guides de déduction peut contenir des requires ou des concepts?

Marshal Clow : les concepts oui, les requires je ne sais pas car je n'ai pas essayé

Marshal Clow donne sa démarche. Quand il définit des guides de déduction, il commence par lister tous les constructeurs (pour std::vector il y en a une quinzaine) et identifie tous ceux qui sont couverts par les guides implicites. Pour le constructeur par défaut, CTAD ne nous aide pas; idem pour un constructeur qui ne prend qu'un allocateur ou un constructeur qui prend une taille et un allocateur (on aurait pu en faire sur la base de typename A::value_type, mais on a choisi de ne pas le faire). Pour les constructeurs de copie et de mouvement, avec ou sans allocateurs, les guides implicites font le travail (si les allocateurs source et destination ne correspondent pas, l'allocateur n'est pas dupliqué). Idem pour ceux qui prennent un size_type et un value_type (et un allocateur). Ceux avec une initializer_list<T> déduisent T. Conséquemment, les seuls guides de déduction explicites sont ceux pour les constructeurs qui acceptent une paire d'itérateurs. Notez que ceci est légal (incluant le paramètre par défaut) ce qui est bien pratique :

template <class It,
          class V = typename std::iterator_traits<It>::value_type,
          class A = std::allocator<V>>
   std::vector(It, It, A = A()) -> std::vector<V, A>;

Ben Deane : est-ce permis d'écrire un guide de déduction pour un type dans std?

Marshal Clow : bonne question. Je pense que non

Marshal Clow poursuit en disant qu'on veut définir clairement les déductions qu'on souhaite suppléer, et qu'il faut écrire des tests... Il se peut que plusieurs de nos souhaits soient déjà comblés par les guides de déduction implicites! Ensuite, si on les estime pertinents, on écrit les guides... Marshal Clow recommande d'écrire des tests négatifs, qu'on veut voir échouer, pour s'assurer de ne pas avoir introduit des déductions qu'on ne voulait pas permettre

Marshal Clow dit qu'il est sage de se poser des questions comme « qu'est-ce qu'un allocateur? » ou « qu'est-ce qu'un itérateur? ». Pour les itérateurs, c'est facile : ils ont des iterator_traits 🙂 Pour les allocateurs, il y a des requis dans le standard

Marshal Clow aborde les pièges. C'est difficile à déboguer (alors faut faire des tests!). Il dit avoir une macro ASSERT_SAME_TYPE(...) qu'il utilise beaucoup pour cela (c'est un test à la compilation sur la base de std::is_same). Il note que shared_ptr<T> n'a pas de guide de déduction à partir de T* pour éviter les bogues découlant de la confusion entre scalaire et tableau. Il raconte des histoires de guerre avec les guides de std::string qui ratissaient trop large et qui ont dû être contraints

Marshal Clow explique les ajouts à CTAD post-C++ 17, soit CTAD pour les alias templates, CTAD pour les agrégats, et CTAD pour les constructeurs hérités (ce dernier pour C++ 23).

Marshal Clow dit qu'en résumé, CTAD est chouette, écrire un guide de déduction est relativement simple, ne pas réussir à déduire quelque chose n'est pas un désastre... Le vrai irritant, c'est l'ambiguïté (p. ex. : quand deux guides fonctionnent pour une construction donnée) alors faut tester!

Q : qu'en est-il de l'impossibilité de suppléer une valeur par défaut pour un paramètre autres que ceux à la fin d'une signature de fonction?

Marshal Clow : je ne sais pas

Q : peut-on utiliser la déduction de templates pour autre chose que des constructeurs?

Marshal Clow : je pense que c'est un autre mécanisme

Q : on peut désactiver CTAD si on n'a pas de primary template.

Marshal Clow : oui

Q : est-ce que CTAD fonctionne avec des NTTP?

Marshal Clow : excellente question. Tu vas avoir à travailler un peu. Par exemple, std::array<T,N> va déduire N de la taille d'un initializer_list<T>

Bonne présentation par Marshal Clow, dynamique et solide sur le plan technique, avec beaucoup d'interactions.

Il y a des beignes au menu ce matin (ça fait une éternité que je n'en ai pas mangé). J'en prends un au caramel (ça se prend bien), un café et une pomme parce que c'est moi (les pommes les meilleurs sont au Québec, cela dit). Je croise au passage Inbal Levi, qui quitte aussi cet après-midi (mais vers Israel) en même temps que moi, alors on va essayer d'organiser un covoiturage pour sauver des frais.

John Lakos est un personnage divertissant; si vous n'avez jamais regardé une de ses présentations, prenez le temps de le faire, puis regardez le titre de sa présentation de ce matin (voir ci-dessous). C'est aussi un architecte senior chez Bloomberg et un auteur à succès alors il a des ressources. Ce matin, on nous accueille avec un petit formulaire et un stylo dinosaure; on remplit le formulaire qui pose des questions quant à la probabilité qu'il y ait de l'urine de dinosaure dans l'eau de notre café ce matin (et quelques autres du genre), on laisse non pas notre nom mais une phrase de passe (pour avoir une forme d'anonymat), on dépose notre formulaire dans une boîte de carton, et on garde le stylo.

Vidéo : à venir

John Lakos – Quantifying Dinosaur Pee, Expressing Probabilities as Floating-Point Values

Note préalable : je ne prendrai assurément pas de notes exhaustives car John Lakos est une bête qui peut passer 300 diapos à l'heure... Faut rester attentifs.

John Lakos explique que la présentation de ce matin est inspirée de travaux sur un livre portant sur des tests, livre qu'il écrit depuis longtemps et pense publier dans 2-3 ans.

John Lakos commence par une variante du problème des anniversaires et de la variation de la probabilité calculée en fonction du nombre de personnes dans la salle. Il s'intéresse à la signature de la fonction qui calculera cett probabilité

(c'est une présentation étourdissante 🙂)

John Lakos frappe un noeud. À partir de 184 personnes, la probabilité est toujours 1.0 ... car on déborde la précision d'un double! On utilise la pleine mantisse et passé un certain stade, on n'est plus proche de 1.0, on est à 1.0 (on peut être beaucoup plus proche de zéro que de un sur un double!). Faut retravailler l'interface et le contrat de la fonction (on passe de sameBirthday(int nbPersonnes) à uniqueBirthday(int nbPersonnes)). On change le nom, on change le contrat, mais on ne change pas la signature.

On passe ensuite à la question en titre de la présentation 🙂 John Lakos propose des dinosaures sphériques et on se bidonne dans la salle. Il travaille les équations avec des unités flottantes et avec des unités discrètes. Il y a de petites variations (les erreurs sur les bits faibles apparaissent). Il tient ensuite compte de la composition (Compounding) comme s'il y avait des intérêts dans un problème financier. Ça joue un peu sur les chiffres. Avec les imprécisions sur les double, on arrive parfois à des aberrations.

John Lakos rappelle que si on joue avec des probabilités, faut poser des questions pour lesquelles les réponses tendent vers zéro. C'est une belle démonstration de ce qui se passe quand on calcule sur des nombres à virgule flottante représentés selon IEEE754

John Lakos roule vite (plus encore!) pour les dix dernières minutes. J'ai de bonnes réponses dans la plupart des cas (pas tous, mais ce qui n'est pas si mal dans les circonstances). Sa grosse conclusion (et la mienne!) est qu'il est préférable de faire des calculs qui nous mènent près de 0 plutôt que des calculs qui nous mènent près de 1 (on a plus de bits pour travailler). Au besoin, reformulez la question  pour que ça se pose dans ces termes.

Vittorio Romeo : et si on voulait présenter l'information sous la forme non-reformulée... Le problème revient, non?

John Lakos : trouve un moyen (symbolique ou autre)?

Q : quand auras-tu le volume 2 de ton livre?

John Lakos : aucune idée. J'ai livré le volume 1, je vais livrer le volume 3, et on verra pour le volume 2, sûrement pas avant au moins six ans.

Q : si la probabilité est si près de 1, est-ce important?

John Lakos : ça dépend du client!

C'était instructif et divertissant... avec une masse d'information démente! John Lakos nous dit par la suite que les stylos devaient être de lui et être très cheap, mais Bloomberg a grogné et il acheté de meilleurs stylos. Il nous donne le portrait statistique des réponses au questionnaire : personne n'a eu toutes les réponses, et en moyenne on n'était pas mal. John Lakos fait tirer des livres 🙂

J'ai mangé une bouchée, pris des nouvelles de Kevin Carpenter, puis je suis allé à un panel sur la concurrence et la sécurité avec Michael Wong, Luca Radu Teodorescu, Timur Doumler et Dietmar Kühl. C'était pas prévu, mais c'était amusant et j'ai pu aider un peu avec quelques questions. Ensuite, je suis allé corriger un peu pour constater que je n'ai plus accès au réseau depuis mon Check-Out... Zut!

Pendant que je corrige, j'écoute distraitement une conférence amusante de David Sankel (il est toujours intéressant), mais je sais que je ne pourrai pas rester jusqu'à la fin alors je ne suis pas aussi attentif qu'habituellement. Je me dirige ensuite vers l'entrée principal de l'hôtel pour constater que mon chauffer n'a pas été annulé alors j'en informe Inbal Levi pour ne pas qu'elle m'attende, j'embarque vers l'aéroport et me voilà en route vers la maison et ma famille que j'aime.

J'ai manqué le Closing Keynote par Herb Sutter dû au fait que je devais prendre l'avion, mais elle a été publiée sur YouTube et est disponible sur https://youtu.be/ELeZAKCN4tY

Et après...

 


Valid XHTML 1.0 Transitional

CSS Valide !