À propos de WG21, Kona 2017

Quelques raccourcis :

Disclaimer

I wrote what follows mostly to keep my students informed of what a WG21 meeting is like, and I do not want to break the ISO code of conduct (I really don't want to do that!), but I do name people when I don't think it has any harmful effect (when discussions are more heated, I try to refrain from identifying individuals) as it might interest my students to see what kind of argument these bright individuals can formulate. Should you think it would be appropriate for me to remove things from this page, please tell me and I will proceed switfly.

Based on a recent (March 2017) clarification of the ISO code of conduct, I have anonymized all in-meeting discussions except for self-evident things like chairs asking for votes (it's an ongoing process, but I'll fully anonymize it as soon as I can).

Grâce à l'Université de Sherbrooke (en particulier, grâce à Jean Goulet et à Claude Cardinal du CeFTI) et au Collège Lionel-Groulx (en particulier grâce à Éric St-Jean), j'ai eu le privilège de participer à WG21, le comité de standardisation ISO du langage C++, qui est mon principal outil de travail et d'expression (outre la langue française elle-même). Il s'agit d'un truc prestigieux pour les informaticien(ne)s comme moi, et j'ai l'honneur de faire partie de ce comité depuis la fin de 2014.

Ce qui suit est une sorte de journal de voyage, avec éléments humains et éléments techniques. Ce ne sera probablement pas volumineux, car je serai là en tant que participant plus qu'en tant que « spectateur intéressé », mais j'essaierai de vous donner une idée de l'expérience.

Qu'est-ce que WG21?

Comme c'est souvent le cas dans les milieux scientifiques, le nom WG21 est peu spectaculaire. On parle ici du Working Group 21, soit le comité de standardisation du langage C++. Pour les informaticien(ne)s, c'est probablement ici que l'explication se suffit à elle-même, étant donné qu'on tombe directement dans leur créneau.

Pour la majorité d'entre vous, par contre, ça reste obscur, alors j'essaie une explication (il se peut que ça ne vous rejoigne pas, mais c'est de bon coeur) :

Le langage C++ existe depuis les années '80. Il a été standardisé par l'organisme ISO en 1998, puis solidifié en 2003 avec des ajustements (relativement mineurs) jugés nécessaires de par l'expérience concrète obtenue depuis C++ 98. Une révision très majeure du langage a été ratifiée en 2011, et C++ 11 est l'essentiel du langage par lequel nous exprimons nos idées aujourd'hui. Une révision mineure (mais fort appréciée) a été ratifiée relativement récemment (C++ 14), et la prochaine mise à jour majeure, C++ 17, est celle sur laquelle nous travaillerons à WG21 pour les prochaines années. Les objectifs de C++ 17 sont très ambitieux, et font saliver les gens qui, comme moi, cherchent à tirer le maximum de ce que ce langage a à offrir.

On me dit que nous sommes ≈300 membres de WG21 sur la planète, et qu'environ cent personnes se présentent aux rencontres du comité (les autres font surtout des contributions par écrit). Pour la rencontre documentée ici, nous serons environ 120.

Pour un peu de bagage supplémentaire sur l'événement, voir :

Pour les journaux de voyage d'autres participants, voir :

Pour des reportages plus « commerciaux » :

Début du contenu technique

Je vais mettre le contenu technique dans des blocs en relief, comme celui-ci. Si vous ça ne tombe pas dans vos cordes, passez par-dessus.

Sur le plan de la procédure, certains débats étant chauds et les gens qui débattent étant mes pairs, je vais m'abstenir de donner dans le nominatif dans ces sections (à moins que ça n'ait pas d'incidence).

Fin du contenu technique

Au préalable

J'ai toujours le coeur gros quand je quitte la maison pour une semaine ou plus, car je m'ennuie beaucoup de ma belle Za et de mes enfants (ce qui n'enlève rien à l'intérêt du travail que nous faisons lors des rencontres du WG21, qui sont passionnantes). Cette fois, je dois l'avouer, c'est pire qu'à l'habitude, et j'ai pensé annuler le voyage la veille du départ, car mon épouse que j'aime et moi avons vécu une épreuve qui aurait mérité que nous restions ensemble pour quelques jours.

Malheureusement, il était trop tard pour annuler le tout, et les conséquences financières auraient été désastreuses, alors je me suis résolu à partir malgré tout.

Jour -1 26 février 2017

Factoïde amusant : Dulles est un lieu dans un jeu de table (Les aventuriers du rail, en anglais Ticket to Ride) auquel nous jouons parfois en famille, et je me demandais où ça pouvait bien être, le nom ne me disant rien. Eh ben, Washington D.C., ça explique que le jeu y ait réservé une place!

Mon chic papa Réal a accepté de m'amener à l'aéroport aux aurores, pour permettre à Za de se reposer (elle le méritait!). Ma mère Lucille a dépanné avec notre plus jeune, Ludo, lorsque les problèmes de la veille ont commencé, alors que Danielle et Jocelyn, les parents de mon épouse, ont pris en charge les deux plus jeunes (Vayda et Ludo) pour nous aider. À tous, d'immenses mercis. Vous êtes des amours, et nous apprécions sincèrement ce que vous faites pour nous et pour les enfants.

Le trajet pour aller à Kona passe de Montréal à Dulles (Washington D.C.), puis à Los Angeles, le tout avec des délais très courts pour passer d'un avion à l'autre, et mon départ de Montréal a été retardé pour cause de glace sur les ailes de l'avion. Le voyage a par contre été bref (et tumultueux; ça brassait!) et nous avons réussi à compenser (légèrement) pour le retard, ce qui m'a permis de ne pas manquer ma connexion vers Los Angeles. Sur ce vol, j'ai eu le temps d'écouter deux épisodes de CppCast, soit celui avec Matt Calabrese et celui avec Brittany Friedman (que je n'ai toutefois pas eu le temps de terminer, mais je poursuivrai dans mon prochain vol). J'aime bien apporter avec moi cette balado, qui est d'excellente qualité et dont le format sied à un voyage comme ceux que je suis appelé à faire (en plus, les animateurs et les participants sont de chics individus!). Pas de goûter (il y avait de la nourriture appétissante, mais je n'ai pas le budget requis), outre une petite galette au caramel vanillé, ma foi très agréable en bouche.

Les gens de l'aéroport Dulles ont été extrêmement gentils et accueillants; de plus, ils ont assurément le meilleur WiFi que j'ai rencontré dans un aéroport jusqu'ici. Bravo! Je prends le temps d'écrire un peu à ma belle Za, et je m'engouffre dans mon deuxième de trois vols aujourd'hui.


C'est un assez long trajet que celui de Dulles à Los Angeles, soit cinq heures et il fait relative et il fait relativement chaud dans l'habitacle. Étant mal assis, j'ai sommeillé un peu, sans plus, mais je me suis fait le plaisir d'écouter La soirée est encore jeune de la veille, en balado (j'ai ri à pleurer; c'était hilarant). Je termine aussi la balado avec Brittany Friedman puis j'écoute celle avec Marshall Clow, un individu extrêmement gentil et fort pertinent, suivi de celle avec Vinnie Falco. Avis à mes étudiant(e)s et à mes collègues : ces balados valent la peine d'être écoutées si vous souhaitez mieux comprendre ce que nos faisons lors d'une rencontre du comité de standardisation. Sur ce vol encore, pas de goûter, outre un sac de mini pretzels.

Seul truc amusant à savoir, vraiment : il y avait un Shih Tzu sur mon vol, dans les bras de sa maîtresse. J'ai pensé à Za qui aime tellement ces chiens au visage écrasé...


Arrivé à Los Angeles, après les délais pour nous permettre de sortir de l'avion, il me restait dix minutes pour me rendre au point d'embarquement de mon dernier avion de la journée. J'ai été chanceux ici encore du fait que l'avion avait un très léger retard (cinq minutes), mais ça m'a permis d'aller au petit coin et de ramasser un bagel canelle et raisins (seule chose au prix pas-trop-déraisonnable à proximité; à peine 2,5 USD... Un sandwich au thon tout simple, c'est quand même 9 USD).

Nous sommes quelques membres du WG21 sur le vol : outre moi-même, j'ai vu Matthias Gaunard, J. Daniel Garcia, Roger Orr et quelques autres dont le nom m'échappe pour le moment. On bavarde brièvement avant d'embarquer pour réduire les frais de taxi en arrivant. J'ai à peine le temps de saluer ma belle Za avant de m'engouffrer dans l'avion.

Le lien WiFi de l'aéroport de Los Angeles est misérable, et ne me permet pas d'accéder à gmail pour collecter les documents que je souhaite lire pendant le vol (sécurité insuffisante). Heureusement, le toujours chic Botond Ballo a une copie archivée sur une puce USB et me la refile, ce qui me permettra d'être un peu plus efficace. Malheureusement, mon vol n'offre pas de prise de courant en classe économique, ce qui réduira ma productivité (moche, car c'est un vol de plus de six heures avec conditions météo de mauvaise qualité – ça brasse beaucoup à l'occasion, mais le pilote nous a prévenus d'office – alors j'aurais voulu profiter du temps au maximum). Roger Orr me fait remarquer que le vol est plutôt vide (plein à je dirais, ce qui est inattendu étant donné que c'est la haute saison à Hawaii). Je poursuis les balados de CppCast : celle avec Stephan T. Lavavej, celle avec Alex Allain et celle avec Björn Fahller; enfin, je bascule à la musique une fois mes balados consommées.

J'aime bien normalement afficher les données de vol à l'écran apposé devant mon siège quand je fais un trajet comme celui-lci, mais notre vol a une autre particularité : il favorise un truc nommé DirecTV, qui permet de regarder la télé américaine pendant un trajet, or cela (a) ne m'intéresse pas beaucoup, et (b) ne fonctionne pas de toute manière une fois au-dessus du Pacifique, donc à peu près vingt minutes après avoir quitté Los Angeles (le voyage entre Los Angeles et Kona se passe à plus de au-dessus de l'océan : l'aéroport de Los Angeles donne directement sur le Pacifique, Kona est une île, et on ne survole pas la terre ferme entre les deux. Conséquence : on a le choix entre payer 8 USD pour regarder un film « surprise » qui tourne en boucle et ne pas payer ce prix et se faire imposer six heures de publicité sur DirecTV et ses vertus. Eh ben.


Nous nous posons à Kona, après avoir rempli les petites cartes affirmant que nous n'avons rien apporté qui pourrait nuire à l'écosystème local. Le pilote nous invite à faire profiter le commerce local et nous dit que nous sommes arrivés sur God's Gift to the World, rien de moins. Faut dire que c'est effectivement un très bel endroit.

Une fois arrivé à l'aéroport de Kona, la question est de savoir si mes bagages m'ont suivi malgré les courts transits... et la réponse est oui (ouf!). Matthias Gaunard a loué une voiture compacte et nous offre de nous amener à l'hôtel, mais nous sommes quatre (moi, J. Daniel Garcia, Roger Orr et un autre dont le nom m'échappe mais qui arrive de Londres) avec bagages alors nous nous séparons un taxi. Sur la route, on échange des banalités sympathiques sur la durée du voyage (Botond Ballo vient de Toronto et a eu un voyage d'une longueur semblable à celle de mon propre voyage; J. Daniel Garcia arrive d'Espagne en passant par l'Allemagne pour faire une ligne directe de cet endroit vers Los Angeles, ce qui est très long). J'en profite pour parler météo avec le chauffeur : ici, tout le monde vit et travaille à l'extérieur, mais la météo annoncée parle de pluie cette semaine. Le chauffeur me dit qu'il pleut ici, mais jamais très longtemps, alors ça ne dérange pas les gens.

Contrairement à mon passage précédent, je ne suis pas dans le même bâtiment que celui où se tiennent la plupart de nos activités (le complexe hôtelier comprend trois tours), mais on parle de 15 secondes de marche au bord de la mer entre les deux, rien de grave. J'avais oublié qu'il y a des torches allumées un peu partout ici le soir, c'est joli. Bon accueil, température chaude (pour moi) mais agréable avec le vent et l'odeur de la mer.

Il est presque 22 h quand nous arrivons à l'hôtel. Je pars à la recherche du code de l'événement pour le WiFi (je l'ai reçu par courriel, mais sans accès Internet, pas facile de le retrouver). Je trouve un petit groupe de collègues qui discutent autour d'une bière (ça parle fort, en particulier entre Louis Dionne et John Lakos, qui discutent de comportement indéfini et de gestion d'erreurs en situation de bris de contrat). Andrew Pardoe me refile le mot de passe; pendant ce temps, une serveuse les informe que c'est le « Last Call », j'en profite pour prendre une bière à rapporter à ma chambre (question de retomber sur mes pattes). John Lakos paie la tournée et m'inclut dans le lot, ce pour quoi je le remercie.

Enfin à ma chambre, petite mais convenable (je suis seul; la dernière fois, j'avais une chambre qui aurait pu loger quelqu'un d'autre, c'était gênant). Je salue Za qui me répond (il esth du matin à la maison), je prends ma bière (les bières locales sont très bonnes ici) et c'est l'heure de dormir un peu.

Jour 0 27 février 2017

J'ai mis mon réveil pourh, heure locale (h du matin à Montréal), car j'ai beaucoup à faire pour me préparer (je vais manquer de temps). Un peu comme la dernière fois, je suis « bloqué pour piratage » dû à mon utilisation d'Internet (trop d'onglets ouverts, la compagnie locale pense qu'on fait ds mauvais coups), ce que je règle par un coup de fil.

J'écoute la radio de Radio-Canada et, à l'émission Médium Large, je tombe sur ma chumette Eza Paventi qui a accueilli une famille syrienne et vient de tourner un documentaire sur l'intégration de ces nouveux arrivants. C'est une belle surprise!

J'ai voulu aller me chercher un café et une bouchée pour déjeuner, mais l'endroit où (de mémoire) je faisais cela lors de mon séjour précédent semble être devenu un restaurant avec déjeuner, mais du genre où il faut s'asseoir, pas du genre où l'on accroche quelque chose avant d'aller prendre une marche. C'est moins dans mon budget, disons (même si ça semble très bon), et j'ai beaucoup de boulot devant moi alors je préfère revenir à ma chambre et essayer le café fourni par l'hôtel (on verra bien). De toute manière, le café ne manquera pas durant la journée.

Remarquez la ligne raturée. C'est que Vicente J. Botet Escriba m'a demandé de présenter p0319r1, que je ne connais qu'en surface, alors que nous avions travaillé p0320r1 ensemble, et j'ai dit « oui » en pensait qu'il parlait de l'autre. Je vais donc devoir me documenter un peu...

En plus d'être en retard dans ma préparation (j'ai une bonne centaine d'articles à lire; j'en ai lu plusieurs hier et ce matin, mais « la pile est haute »), j'ai constaté que j'ai plusieurs trucs à présenter cette semaine, la plupart devant LEWG, soit :

Dans la plupart des cas, ce sont des documents proposés pour Issaquah, mais que ls délais ne nous avaient pas permis de traiter. Je vais aller voir Jeffrey Yasskin, qui dirige les travaux de LEWG, pour lui demander de me donner le temps de les relire pour me rafraîchir la mémoire, question de faire un bon travail. Je lui en glisse un mot, et il accepte gentiment de m'avertir un peu d'avance (c'est un jeune papa, alors je pense qu'il est sensible aux débordements de boulot et de vie courante).


La salle se remplit peu à peu, et les travaux débutent àh 30. Les nouveaux visages sont rares cette fois, mais c'est une rencontre qui se prête moins que d'autres à accueillir des nouveaux participants; l'objectif principal est de ficeler C++ 17, ce qui serait un immense pas en avant. On survole rapidement le code d'éthique, les règles comportementales d'usage, la procédure décisionnelle, et ainsi de suite, mais on a pour objectif de faire en sorte que la plénière soit brève car le boulot déborde de partout, alors on escamote la présentation individuelle durant la plénière.

On a dix pays représentés formellement ici cette semaine (États-Unis, Canada, Grande-Bretagne, Suisse, Russie, Espagne, Finlande, France, et il m'en manque deux). C'est important de tenir le compte car cela peut avoir un impact sur les votes, dû aux procédures d'un organisme comme ISO. Je suis sur les feuilles de présence officielles maintenant (contrairement à mes deux premières participations), étant officiellement membre du répertoire ISO, ce qui fait toujours un petit velours.

On procède à l'adoption d'une douzaine de WD pour démarrer les travaux de la semaine. Les gens ont l'occasion de se prononcer sur les rapports livrés par les éditeurs de ces documents, mais personne ne le fait. Detlef Vollmann mentionne qu'il manque un numéro de document pour celui sur les coroutines, mais Herb Sutter indique que c'est un bogue relié aux délais administratifs (le numéro a été demandé). Herb Sutter dit aussi aux éditeurs qu'une adaptation éditoriale doit être fait à tous les documents cette semaine pour fins de respect des règles en vigueur. John Spicer demande si cela affectera les numéros de clauses, en particulier pour les clauses du standard lui-même (un monstre de plus de 1500 pages, tout de même, auquel on trouve ds références partout dans le monde); Herb Sutter dit oui, désolé. Désormais, tout document ISO devra avoir des clauses 1, 2 et 3 avec un contenu très spécifique, et c'est comme ça, alors faut changer la numérotation de tous les documents pour la décaler (et, surtout, décaler les références aux documents en question). Morale de cette histoire : référer au standard par les noms de sections, pas par leurs numéros.

Les Working Group Chairs ont l'opportunité de s'exprimer :

Clark Nelson indique que son passage en tant que Chair de WG21 arrive à terme à la fin de 2017, et qu'il envisage la retraite. La porte est ouverte pour recevoir des candidatures pour le remplacer. John Spicer s'est offert, en tant que Chair ou que co-Chair. Il faudra aussi un secrétaire pour remplacer Jonathan Wakely à Toronto, car il deviendra papa.

Jens Maurer explique la mécanique de la semaine, la répartition des groupes de travail dans les pièces, l'attribution des projecteurs, etc. Il semble que la journée pour EWG et CWG commencera dans la grande salle pour fins de discussion regroupant les deux. Les sessions de soirée prévues sont mardi soir (19 h 30, SG7 – réflexivité) et jeudi soir (direction général du langage); il se peut qu'il y en ait une pour SG14, mais Michael Wong n'est pas convaincu que ce soit présent.

Walter E. Brown demande aux gens qui tiennent à jour les divers Wiki d'essayer d'indiquer « ce qui s'en vient » pour faciliter la planification du temps.

On arrête àh 5, pour dix minutes (question de laisser les gens se déplacer). Je reste dans la grande salle pour les travaux de CWG.

Ville Voutilainen dirige les travaux de ce groupe de travail conjoint. On a plusieurs NB Comments qui demandent une décision commune des deux groupes.

US24 ne semble pas accompagné d'une proposition écrite. Le consensus semble être que l'idée est intéressante mais qu'il est trop tard pour procéder sans proposition sur la table. Rejeté faute de consensus

Laisser les implémenteurs d'apposer constexpr si cela semble approprié à leurs yeux est mis de côté, car l'impact est trop gros pour être considéré cette semaine (cela dit, on y revient plus tard ce matin; voir les discussions sur GB28)

Certains souhaitent renommer Structured Bindings, par exemple par Decomposition Declarations. C'est un débat de sémantique, vraiment, et il est tard pour renommer un tel mécanisme, comme le rappelle quelqu'un (après tout, les gens ont commencé à utiliser le nom sur les réseaux sociaux). Richard Smith pense que les deux termes ont leur place : un pour le mécanisme, et un pour ce qu'on en fait; il indique que le nom « public » du mécanisme peut demeurer Structured Bindings, et que l'on peut y aller de plus de précision dans le texte normatif. Quelqu'un demande pourquoi ne pas simplement renommer Decomposition Declarations vers Structured Binding Declarations. Quelqu'un pousse dans cette direction, qui semble pouvoir minimiser les irritants. Quelqu'un soulève une question importante sur la nomenclature des messages d'erreurs que soulèveront les compilateurs, souhaitant éviter la confusion. Quelqu'un revient sur le besoin d'avoir deux noms pour deux mécanismes, et dit ne pas voir le problème. On échange sur le besoin d'un nom dans certains cas. Quelqu'un est d'avis que CWG devrait choisir le nom dans le texte normatif. Un participant mentionne que le mot « déclaration » peut nuire dans le futur car certaines propositions sur la table peuvent mener à la matérialisation d'un objet en l'absence d'une déclaration. Quelqu'un pense que Structured Bindings devrait être le Term of Art pour les objets introduits par une Decomposition Declaration. Ville Voutilainen prépare un vote indicatif :

Quelqu'un demande s'il y a lieu de prendre un vote pour le statu quo, à titre indicatif. Ville Voutilainen dit que le statu quo tient si nous n'approuvons pas de changement. Quelqu'un rappelle que nous essayons de nommer deux choses distinctes par un seul nom. Dans la phrase suivante :

auto [a,b] = f();

... la déclaration entière serait selon lui une Decomposition Declaration alors que a et b seraient des Structured Bindings (pour le moment, a et b sont simplement des identifiers, ce qui est vague et d'une utilité discutable).

Brève pause dans les travaux, le temps de remplir nos tasses de café. Il est 10 h. Certains dans la salle trouvent ces débats terminologiques inutiles, mais c'est bien sûr le coeur des travaux d'un groupe tel que CWG, et pour ces gens, un nom inapproprié est un frein à la productivité. Choc des cultures, je présume. Je me sers un café, Gor Nishanov passe dire bonjour (quel individu adorable!), on discute informellement ici et là, et on recommence.

GB28 porte sur constexpr dans la bibliothèque. Quelqu'un explique que noexcept a été appliqué de manière sélective par les implémenteurs avant de devenir obligatoire, et pense que constexpr pourrait avoir droit au même traitement, mais pour le moment les deux sont traités différemment (liberté pour noexcept, contrainte pour constexpr). Quelqu'un questionne la portabilité, pour le code client, des résultats de cette expérimentation (c'est « hautement détectable »). Quelqu'un retrace l'historique des échanges à ce sujet. Quelqu'un rappelle que noexcept est maintenant aussi « hautement détectable », dû à nos changements les plus récents, et ne voit pas cela comme un obstacle. Quelqu'un signale que ceci peut causer des violations d'ODR et influencer le lieu de l'initialisation des variables. Quelqu'un y voit un risque de fuite dans l'ABI d'une implémentation, mais ne pense pas que ce soit dramatique. Quelqu'un rappelle que les bibliothèques ne sont déjà pas ABI-compatibles entre elles. Quelqu'un y voit un lieu fécond pour ouvrir la compétition entre les implémentations. Quelqu'un distingue les implémenteurs de bibliothèques standards et les individus chargés de leur entretien; il craint l'impact de ce changement pour le second groupe, et pense qu'il deviendra rapidement difficile pour un programme C++ de migrer d'une bibliothèque à l'autre. Certains discutent de la possibilité d'accepter ou non les extensions à constexpr. Quelqu'un se dit d'avis qu'il est un peu tard pour aborder une question de cette importance. Quelqu'un suggère qu'on peut ne rien faire tout simplement, car les compilateurs sont ici tout à fait dans le domaine des extensions et peuvent faire comme ils le font avec d'autres extensions aujourd'hui. Quelqu'un indique qu'il est difficile d'ajouter constexpr à la bibliotheque standard sans expérimentation préalable, ce qui le rend favorable à cette ouverture.

On vote, et le consensus semble être que ça ne passe pas. Quelqu'un suggère que l'on reprenne la réflexion au début des travaux pour C++ 20.

On aborde ensuite la question des Deduction Guides. L'auteur original de cette proposition prend le plancher. Le pauvre est en béquilles alors on l'aide à transporter son matériel. Il s'assied, dû aux circonstances, et présente les fruits de sa période d'expérimentation. Il explique avoir expérimenté avec plus de 100 classes et avoir reçu beaucoup de critiques constructives. Dans le cas des guides implicites, quelqu'un dit que plus de des classs évaluées se sont comportées exactement comment on aurait plus le souhaiter. Pour les autres, il a fallu suppléer des guides explicites pour combler certains manques des guides implicites (surtout dans le cas des constructeurs de copie et de mouvement). Il mentionne vector qui a demandé trois retouches, pour tenir compte aussi du constructeur de séquence. Les programmes dépendant beaucoup de métaprogrammation ont été les plus susceptibles d'avoir besoin de guides explicites.

Quelqu'un dit que le recours le plus récurrent aux guides explicites est pour forcer la décrépitude (Decay) des types, surtout pour les références. Il mentionne en particulier std::pair<const T&,const T&> dans le cas où T est un tableau. Certains constructeur utiles comme le constructeur de séquence ne seront pas déductibles implicitement à partir du contexte, comme le cas vector(It,It) qui doit générer un vector<typename iterator_traits<It>::value_type>. La question des allocateurs a aussi demandé un peu de soins, de même que le cas shared_ptr(T*) qui déduit implicitement un non-tableau. De manière un peu surprenante, = delete n'a pas été nécessaire, outre un cas limite. Cependant, quelqu'un est d'avis que = delete serait utile pour les guides implicites des types unique_ptr et shared_ptr (bien qu'il y ait des voies de contournement; ce serait un atout, pas un requis). Quelqu'un constate que les règles existantes permettent de masquer le constructeur de copie dans des contextes où il aurait été à privilégier, et pense que l'ordre de certaines règles devrait être revu pour placer le guide de déduction plus bas dans les cas à considérer. Il estime que les guides implicites sont une bonne chose, dans l'ensemble. Quelqu'un trace un lien avec Java, qu'il utilise au quotidien : le langage est si verbeux et demande tant d'écriture de la part ds programmeuses et des programmeurs que lui et ses collègues tendent à privilégier des générateurs de code; sa perception est que les Deduction Guides, surtout ceux implicites, réduisent beaucoup la répétition inutile de code (le Boilerplate Code).

Quelqu'un prend le relais et dit qu'il était sceptique au préalable mais que son expérience est plutôt positive dans l'ensemble.

Ville Voutilainen demande l'opinion de CWG. Le consensus semble être de ne pas prendre le temps de l'assemblée toute entière et de ramener cela à même le groupe de travail, pour fins de productivité.

Quelqu'un apporte un exemple :

tuple<int,int,int> x;
tuple a = x; // tuple<int,int,int>
tuple b(x); // tuple<int,int,int>
tuple c{x}; // tuple<int,int,int>?
tuple c2 = {x}; // tuple<int,int,int>?
auto d = tuple{ x }; // tuple<int,int,int> ou tuple<tuple<int,int,int>>?
tuple e({x});
list y{ ... };
reversed(reversed(y)); // avec des reverse_iterator

On a des échanges sur la cohérence de nos énoncés. On souhaite une initialisation uniforme, après tout, malgré la tare de vector<int> où les accolades et les parenthèses entraînent des initialisations distinctes. Certains poussent pour que le sens de c et d soit uniforme. Quelqu'un parle de la difficulté de comprendre les intentions à partir du code dans le cas d'un tuple, et pense que d ne devrait pas donner un tuple<tuple<...>> (dans un tel cas, selon lui, mieux vaut laisser le code client expliciter son intention).

Quelqu'un mentionne que dans un cas où il existe plusieurs surcharges à l'initialisation, nous avons des mécanismes qui fonctionnent; il ne souhaite pas un remède qui soit pire que la maladie, et il n'est pas convaincu que les Deduction Guides éliminent la totalité des fabriques. Quelqu'un mentionne l'ambiguité du mot « simple » (ici, {1} et {1,2,3} mèneraient à des déductions distinctes). Quelqu'un mentionne qu'il serait à l'aise d'expliciter tuple dans les cas complexes. Quelqu'un parle de pratique préexistante et mentionne future, où nous cherchons à déballer les future<future<T>> pour fins d'enchaînement dans des continuations. Quelqu'un mentionne d'autres cas de « types emballés », en particulier les intervalles. Quelqu'un dit que le déballage implicite, qui fait disparaître des types, peut surprendre et compliquer le débogage. Quelqu'un insiste sur l'importance d'un comportement homogène pour faciliter la programmation générique. Quelqu'un aimerait que le concepteur d'une bibliothèque ait le contrôle sur la forme (explicite ou implicite) du déballage qui se produira. Quelqu'un pense que nous avons ce contrôle : un guide explicite. Quelqu'un mentionne qu'un guide explicite changerait les comportements de a et b. Quelqu'un mentionne optional<T> qui est un cas connexe.

Quelqu'un se dit d'avis que les cas spéciaux, qui déballent implicitement, soient les cas particuliers, pas le cas général. Il n'aime pas l'effet de surprise qui vient avec une perte implicite de sémantique. Quelqu'un est d'accord dans la mesure où l'auteur d'une bibliothèque peut rendre ce comportement de déballage implicite si cela lui semble à propos. Quelqu'un pense que l'immense majorité des cas d'utilisation « ordinaires » ne sont pas des tuple<tuple<...>> ou des optional<optional<T>>, et recommande de ne pas modifier le comportement par défaut proposé.

Ville Voutilainen suggère que l'on aille manger, et que la décision se prenne cet après-midi avc EWG seulement. CWG se rencontrera en début d'après-midi pour discuter des modules. Il se peut que l'on se regroupe tous ensemble pour discuter de std::launder() par contre.

N'ayant ni temps, ni budget, je vais me chercher un sandwich du jour au Subways le plus près. Je croise Billy Baker, arrivé ce matin trente minutes avant la plénière car, bien qu'il habite aux États-Unis, les aléas du vol (un avion surchargé, des retards, des transferts imprévus) l'ont forcé à prendre cinq vols sur deux transporteurs distincts pour arriver jusqu'ici. Disons qu'il semble fatigué.

Une particularité de CWG est que la plupart des participants travaillent aussi pendant les pauses (je ne suis pas le seul à être débordé), ce qui fait que pendant le dîner, je partage la salle avec Mike Miller , Roger Orr et Jens Maurer.. Difficile de cacher le bruit constant du ventilateur de mon laptop sur-le-point-de-rendre-l'âme, ce pourqui je leur offre mes excuses. Disons que je suis chanceux qu'ils aient le sens de l'humour... et que je suis vraiment dû pour un nouvel appareil.

Pendant que la pièce se remplit, et que les collègues aux oreilles les plus sensibles s'éloignent de mon bruyant laptop, on échange un peu sur les travaux de WG21 auxquels je participe, et sur la perception de relative insécurité de C++ que peuvent avoir des individus qui n'ont du langage qu'une vision quelque peu... dépassée, disons. John Spicer se permet une boutade à l'effet que la plupart des programmes C++ qui meurent sont en fait des suicides, et on se bidonne un peu.

On commence les travaux.

D0583R0 – Modules: Contexts of Template Instantiations and Name Lookup

Quelqu'un prend le plancher et explique les efforts de clarification du propos.

Quelqu'un demande si la définition d'un template doit apparaître dans l'interface d'un module. Réponse affirmative.

Quelqu'un estime que les règles existantes doivent être enrichies pour faire le lien entre les pratiques existantes et leur application dans le contexte des modules. Quelqu'un mentionne avoir essayé de le faire, mais ne pas y arriver. Il dit avoir produit un exemple pour illustrer l'application des règles déjà présentes dans le texte du standard (exemple qu'il présente), mais ne pas avoir trouvé de « trou » dans les règles existantes. ADL lui a été d'un grand secours.

Quelqu'un mentionne les règles de P0500 qui, selon lui, pourraient être clarifiées dans le contexte de modules, ce qui pourrait réduire les préoccupations.

Quelqu'un met de l'avant un exemple concret :

module Z;
export struct Z {};
// ... module A
module A;
export template<ltypename X, typename Y, typename Z>
   void f(X x, Y y, Z z) {
      g(x);
      g(y);
      g(z);
   }
import Z;
void g(Z, int = 0);// ici, si le code client utilise f, dans lequel des modules cherche-t-on Z?

La question qui le préoccupe est de savoir dans lequel ds modules la fouille pour Z doit être faite. Quelqu'un ne souhaite pas que l'on fouille tous les modules possibles pour s'en sortir. Quelqu'un démontre le risque de générer des cycles dans les appels.

Une autre préoccupation que soulève quelqu'un est le cas où une fonction serait écrite pour s'appliquer sur un type défini dans un autre module. Il faut éviter que le type ne soit jamais trouvé. Ceci peut survenir dans le cas d'un namespace réparti dans plusieurs modules. Quelqu'un fait un parallèle avec la relation entre <iostream> et <iomanip>, où ce dernier est en pratique une sorte de complément au premier. Il faut une terminologie pour décrire ces règles. Quelqu'un dit avoir essayé d'exprimer cette idée avec les module partitions discutées à Issaquah, mais ne pas avoir eu le succès attendu. Quelqu'un exprime des craintes dans un cas où un même type est déclaré dans plusieurs en-têtes; à ses yeux, il n'est pas clair sur la base des règles existantes de savoir dans quel module fouiller pour en trouver la définition.

Quelqu'un propose un autre exemple :

module A;
export struct S {};
// ...
module B;
import A;
export f(S);
// ...
import A;

Quelqu'un décrit les règles implémentées dans son compilateur, et met de l'avant les cas où le Name Lookup seul ne suffit pas.

En fait, la plupart des gens ici s'entendent sur ce qui doit être fait, mais il ne semble pas y avoir d'accord sur la clarté de la spécification en ce sens. Quelqu'un trace un graphique sous forme tabulaire pour expliquer le contexte de visibilité des types selon les cas d'exposition et de consommation envisageables. Quelqu'un dit que les règls existantes parlent de contexte, de points d'instanciation; quelqu'un fait remarquer que les modules sont de multiples contextes, ce qui demande clarification à ses yeux.

Quelqu'un dit que dans un cas comme f(T&,U&), il faut débuter par le contexte d'instanciation; si on trouve le type recherché dans le namespace de T, c'est réglé. Idem pour le namespace de U. Les ambiguïtés possibles sont les mêmes qu'à l'époque pré-modules.

Quelqu'un suggère le cas où H.h déclare struct Z, module A inclut H.h et définit f(Z), et le code client inclut H.h, définit sa propre version de f(Z) puis importe l'interface de A. Y a-t-il conflit?

Autre exemple :

// T.h
struct T { };
T operator+(T,T);
// ...
#include "T.h"
import F;
module M;
void g(T t) {
   T t;
   f(t);
}
// ...
module F;
export template<class T> void f(T x) { x + x; }

Quelqu'un pense qu'on devrait s'abord s'assurer que le cas non-template soit bien compris d'abord. Dans l'exemple ci-dessus, la terminologie semble fonctionner. Quelqu'un mentionne par contre qu'une partie du travail est réalisé dans une autre unité de traduction; c'est à son avis la visibilité dans cette autre unité de traduction qui est obscure. L'exemple ci-dessus fonctionne, cela dit.

Quelqu'un ramène l'idée de namespace partitions, qui traçait des « liens moraux » entre fonctions et types associés mais logés dans des unités de traduction disjointes.

Quelqu'un essaie de paraphraser sa compréhension de la vision véhiculée par le texte. Un accord s'installe quant aux termes tels que paraphrasés. On convient qu'il faudrait ramener le concept de namespace partition mais le lier plus efficacement aux règles de déduction d'ADL.

Une discussion s'ensuit à propos du cas où un même type « global » (pris d'un fichier d'en-tête) est défini dans plusieurs fichiers. Traditionnellement, le modèle lexical rend illégale une double définition d'un même type dans une même unité de traduction. Un exemple suit :

module M X.h module N
#include "X.h"
// ce qui précède «module» est
// dans le «module global»
namespace Q {
   X operator+(X,X);
}
module M;
export template <class T>
   void g(T obj) {
      return obj + Q::X();
   }
void j(Q::X x) {
   g(x);
}
namespace Q {
   struct X{};
}
#include "X.h"
module N;
import M;
void h(Q::X x) {
   g(x);
}

Ceci fait embarquer ADL pour la peine. Quelqu'un est d'avis qu'on ne trouve pas l'opérateur + ici sur la base du texte existant.On échange sur la question de savoir si c'est un bogue dans la spécification, ou s'il s'agit d'une acte malicieux (auto-malicieux?) de la part de la programmeuse ou du programmeur pour cacher un nom. Quelqu'un est d'avis que le texte reflète l'intention dans ce cas : l'erreur de desing à ses yeux tient au non-groupement des opérations sur un type avec ce type.

Quelqu'un demande si l'interaction entre le « monde traditionnel » des en-têtes et le « nouveau monde » des modules est la source des difficultés. Quelqu'un dit que les deux vont interagir en pratique, et ce pour longtemps, donc que les deux doivent fonctionner ensemble, par design. Il se dit d'avis que l'exemple sous discussion est excellent pour faire la démonstration de pratiques saines ou malsaines de programmation. Quelqu'un dit que l'opérateur + devrait en fait être un détail d'implémentation dans ce cas-ci (ça devrait s'appeler g_impl()). Gabriel Dos Reis montre comment il devient important de ne pas rendre les détails d'implémentation visibles par voie d'ADL.

On en est rendus à :

// X.h
namespace Q {
   struct X { };
}
// ...
#include "X.h" // (global module)
namespace Q {
  X operator +(X,X); // private implementation detail
}
module M1;
export template<class T>
   void g(T t) { t + Q::X(); } // takes X from this TU and from the M2 TU
void j(Q::X x) {
  g(x);    // ok
}
// ...
#include "X.h" // global module
module M2;
import M1;
void h(Q::X x) {
  g(x);    // ill-formed, can't find operator+
}

Quelqu'un propose un autre exemple :

module A;
export template <class T>
   void f(T t) {
      return t + t;
   }
// ...
module B;
import A;
export template <class T>
   void g(T t) {
      f(t);
   }
// ...
struct S {};
S operator+(S, S);
module C;
import B;
export template <class T>
   void h(T t) {
      g( (t, S()) ); // opérateur virgule, sans commentaire
   }
// ...
import C;
void i() {
   h(0);
}

Je ne commenterai pas le recours à l'opérateur , dans l'appel à g() dans le module C, sauf pour dire que Quelqu'un sort tout droit des profondeurs de l'enfer  . On convient tous que traditionnellement, ceci fonctionnerait à partir de fichiers d'en-tête car le contexte d'instanciation de f(T) serait la ligne juste avant la fonction i(), mais dans ce cas-ci, le contexte d'instanciation de f(T) est le module B. Le problème semble être la mémoire que le compilateur doit avoir des multiples unités de traduction impliquées dans la navigation d'un appel de fonction...

On prend une brève pause vers 15 h. Les discussions se poursuivent.

Quelqu'un revient d'une séance avec EWG où les discussions ont porté sur la possible suppression de l'une des règles associées à std::launder() lorsqu'un objet existant est remplacé par un autre objet du même type par voie de Placement New, alors qu'un pointeur menait sur l'objet a priori, pour déterminer la validiité d'accéder au nouvel objet à travers l'ancien pointeur (à savoir : doit-on passer par std::launder() ou non dans un tel cas?).

Il semble que le consensus n'ait pas été atteint.

On se repose un peu, dix minutes, puis Hubert Tong parle d'un cas qu'il a rencontré où un type pourrait avoir en même temps une taille nulle et non-nulle. On se bidonne un peu, mais c'est de la terminologie pas tout-à-fait simple.

Quelqu'un reprend la parole et cherche à clarifier sa pensée quant à la provenance d'un mot apparaissant dans le module global. Quelqu'un dit que dans le plus récent exemple discuté, il pense que le lookup est fait dans le module C, ce qui demande de retracer le nom global S du point où il a été défini. Pour tous les modules autres que le module global, il n'y a pas de besoin de réaliser une telle trace; le problème survient strictement dans le module global. Quelqu'un est d'accord; on veut que le code existant fonctionne, et c'est une conséquence.

Quelqu'un demande pourquoi cette trace est requise; quelqu'un rappelle que dans l'exemple dont on parle, C::S n'est pas directement visible de D. Quelqu'un pense qu'on peut modéliser la séance de points d'instanciation possibles, pour fins de visibilité, de manière linéaire. Quelqu'un demande si les règles sont les mêmes dans le cas où le module est explicitement nommé, mais quelqu'un pense que ça peut être un cas à part. Pour le moment,§14.6.4.1 [temp.point] donne les règles actuelles. On devrait pouvoir rediscuter de tout cela mercredi.

Coroutines

Quelqu'un dit que Gor Nishanov a fait les changements demandés. Il souhaite savoir si nous le faisons revenir pour en parler ou si on détermine que le document, incluant ces modifications, est prêt pour un vote le menant au statut de PDTS pour vendredi.

Quelqu'un pense qu'il serait sage de le revoir, entre autres pour discuter du passage de paramètres (par copie) et de la possibilité de réaliser Copy Elision, deux éléments techniques qui, selon lui, ne sont pas nécessairement clairs dans le texte proposé. On le contactera donc.

CH2 – volatile

Quelqu'un ìndique que cette question temrinologique a été discutée lors de téléconférences préalables. On y jette un bref coup d'oeil, puis on convient qu'il y a lieu de le présenter vendredi.

P0488R0

On pense le porter pour un vote vendredi.

GB29

Quelqu'un voit ceci comme un changement de terminologie, pas comme un changement normatif. Il pense que les gens souhaitent une manière homogène de faire de la taille une propriété des types, pour dire « an object occupies n bytes », ce qui ne veut pas dire la même chose que « an object owns n bytes ». Les bits de padding jouent ici dans le choix des mots, et il faut tenir compte du padding interne au type (incluant la partie parent) dans l'écriture.

Quelqu'un fait aussi remarquer que dans le cas où un objet contient du padding, sa zero-intialization peut ne pas remplir tous les bits du substrat avec des zéros.

GB15

Quelqu'un pense qu'il serait sage de l'examiner cette semaine en vue de C++ 17, car elle a un impact normatif. Il propose le texte qui résoudrait Core Issue 2011. Unclear effect of reference capture of reference. En effet, le texte existant laisse entendre la possibilité de capturer une référence par référence, ce qui n'a pas vraiment de sens.

On pense le porter pour un vote vendredi.

GB66

Celle-ci est reliée au remplacement d'operator delete(void*,size_t) qui devrait être accompagnée d'un remplacement d'operator delete(void*) par conformité. Quelqu'un va essayer d'écrire quelque chose.

GB68

Quelqu'un rappelle que celle-ci, à propos d'un usage inapproprié du nom Literal Type, a été discutée à Issaquah. Quelqu'un s'en occupe.

JP3

Quelqu'un pense que c'est un changement éditorial. Quelqu'un pense que c'est un cas où nous souhaitions explorer une terminologie alternative. Les notes sur le Wiki d'Issaquah ne sont pas claires (c'est peut-être ma faute), d'indiquant pas les raisons. On parle d'un Placement New sur un objet en mémoire statique ici.

Quelqu'un se demande si la création d'un objet en mémoire statique impacte le choix de mots ici. Quelqu'un dit que la création dynamique d'un objet peut mener à un appel au destructeur statique. Quelqu'un pense que le sens donné au mot object dans cette section, soit « an object is a region of storage », est le sens antérieur à C++ 17.

Quelqu'un demande si le qualification non-allocating peut être appliqué au Placement New dans ce contexte. Quelqu'un dit que c'est une terminologie non-normative, mais Quelqu'un pense que ça peut suffire. §5.3.4 p. 16 parle de « If the allocation function is a non-allocating form (§18.6.2.3)... »

Quelqu'un demande si operator new retourne un objet ou un espace d'entreposage. Quelqu'un pense qu'on parle d'un espace d'entreposage, qui délimite la durée de vie qu'on y placera.

On accepte JP3 tel quel, outre des retouches éditoriales. Quelqu'un mentionne que le pointeur retourné peut ne pas être sécuritaire; Quelqu'un ne se sent pas terriblement préoccupé. On peut le passer comme un changement éditorial, pas besoin d'un vote.

CA12

Cette demande tient à clarifier la situation dans un cas comme celui-ci :

#include <new>
int bar() {
   alignas(int) unsigned char space[sizeof(int)];
   int *pi = new (static_cast<void *>(space)) int;
   *pi = 42;
   return [=]() mutable { 
      return *std::launder(reinterpret_cast<int *>(space));
   }();
}

Quelqu'un fait remarquer que le tableau capturé n'est pas nécessairement bien aligné pour le type qui y a été déposé. Devrait-on copier l'alignement d'origine? On pense que oui.

Quelqu'un demande si on a le droit de faire ce changement dans les circonstances, car c'est un bogue (obscur!) qu'on vient de découvrir. Quelqu'un indique que ça va nous exploser au visage avec les Structured Bindings aussi; cela dit, on réglera ça pour C++ 20, car c'est un bogue qui remonte à C++ 11.

Quelqu'un demande si std::launder() est utile ici. Quelqu'un dit que si, en particulier si on enlève la λ, car reinterpret_cast ne s'applique qu'à des types qui sont pointer-interconvertible. Quelqu'un mentionne que le bit_cast qui s'annonce va nous aider, en particulier dans le cas de la « lecture d'objets » sur un lien réseau; dans ce cas bien précis, un bit_cast est une approche plus pertinente qu'une danse faite de std::launder() et d'un reinterpret_cast.

Quelqu'un pense que faire fonctionner ce cas est important pour d'autres situations, en particulier optional<T>. On convient d'en faire un cas à part entière.

Quelqu'un remarque que le standard contient au moins trois descriptions distinctes des règles de copie d'un tableau (capture dans une λ Structured Bindings; membres d'un objet). Faudrait en profiter pour ramener ça à un seul cas.

Reformulation de la section [expr.prim.lambda]

Quelqu'un explique que cette nouvelle section fait surtout du déplacement de texte, mais est suffisamment différente de l'originale pour mériter notre attention.

Ça nous convient. Il y a quelques exemples adorables là-dedans.

lia-idee.pdf

Les références de §1.2 [intro] ont été mises à jour, et permettent de définir certains termes qui étaient utilisés sans être définis auparavant.

La clause ajustée est dans la section du standard « appartenant » à CWG, mais il serait sage de consulter LWG aussi puisque ça les touche.

Quelqu'un fait remarquer que l'une des références est incomplète (il manque une date).

Il est 17 h ici, et ce fut une grosse journée alors nous fermons les livres sur les travaux de CWG jusqu'à demain matin,h, ou plutôt juste après les discussions sur les concepts chez EWG, car cette discussion implique plusieurs personnes ici et on parle d'un sujet d'intérêt général pour le comité dans son ensemble.

Je suis revenu à ma chambre pour parler un peu à mon amoureuse Za et à ma grande Marguerite, suite à quoi je suis allé me chercher une salade de papaye au resto Thaï non loin. Sur le chemin, j'ai croisé Michael Wong avec qui j'ai bavardé un peu (quel chic type, vraiment!). On nous a arrêtés pour nous poser des questions sur SG14, et j'ai eu droit à des félicitations pour mes travaux sur les exceptions des deux dernières années (ça fait drôle de se faire reconnaître par des inconnus). Au retour à ma chambre, j'ai parlé un peu à nouveau à Za, mangé ma salade, lu quelques trucs (la pile de trucs à lire demeure très haute) et je suis allé me coucher... Il n'est pas encore 20 h, heure locale.

Jour 1 28 février 2017

Je me suis levé versh 30 car ma belle Za avait un rendez-vous médical auquel je voulais participer (de mon mieux) à distance (vive Skype dans ces moments!), et nous avons tout de même cinq heures de décalage horaire l'un avec l'autre. Pour les curieuses et les curieux, les nouvelles étaient encourageantes, mais le stress pré-voyage n'est pas encore derrière nous et je me sens bien loin des miens.

Douche, café (celui de la chambre est correct; en général, le café à Hawaii est excellent par contre, et beaucoup moins cher que le café hawaïen auquel nous avons accès au Québec), puis beaucoup de lecture car j'ai un retard fou sur ce plan. Ce matin, CWG ne se réunira pas àh car EWG discutera des concepts, l'un ds plus importants sujets dans le monde de C++ depuis des années, et de gros noms présentent des designs compétiteurs. Comprendre les enjeux (personne dans ce dossier n'est bête, en fait c'est tout le contraire) demande du temps et beaucoup d'attention, mais j'ai littéralement des centaines de textes à lire, et ils ne sont pas simples.

Sans surprises, bien que j'en aie lu beaucoup, je n'ai pas épuisé la liste des textes sur les concepts au moment de mon arrivée dans la salle où se tiennent les rencontres d'EWG, versh 45. Courte discussion amicale avec l'ami Walter E. Brown, toujours aussi charmant. L'atmosphère est fébrile ce matin.

Hier, bien que je ne l'aie pas indiqué, j'avais un peu de difficulté à lire les projections sur le grand écran de la salle de réunion. Je pense que c'était une combinaison d'un projecteur de qualité insuffisante pour cette salle et d'une légère baisse de la qualité de ma vue à longue distance. Triste, mais je vieillis, manifestement. Ce matin, je me suis assis un peu plus près (au centre de la salle plutôt que derrière), et le projecteur semble de meilleure qualité, ce qui me permet de tout voir beaucoup plus clairement.

Quand tous les principaux acteurs pour l'enjeu clé du matin sont arrivés, les travaux se mettent en branle. Herb Sutter recommande aux gens de centrer leurs arguments sur des bases objectives (rétroaction d'usagers, expérimentation, ce genre de truc) pour éviter des dérapages.

On hésite entre faire débuter les présentations par Bjarne Stroustrup ou Richard Smith, qui amènent des visions différentes à la discussion; c'est à Bjarne Stroustrup que revient l'honneur en fin de compte. Sa proposition est P0557R0.

P0557R0 – The Future of Generic Programming

Bjarne Stroustrup trace un historique des travaux sur les concepts, depuis 1987. Les objectifs clés sont les mêmes depuis le début : interfaces à coût nul, bien spécifiées, et expressivité maximale. Une partie des objectifs est atteinte déjà par les templates (Turing-Complete, plus rapides que le code écrit à la main), mais nos interfaces mènent à des messages d'erreurs beaucoup trop complexes. Plusieurs jalons dans l'avènement des concepts au fil des ans sont présentés, jusqu'à leur implémentation dans g++ pour fins d'expérimentation.

Bjarne Stroustrup montre comment la programmation générique peut devenir aussi simple que... la programmation tout court. Les templates ne permettent pas tout à fait cette simplicité, malgré leurs atouts. Les concepts sont des prédicats statiques sur un ou plusieurs types, vraiment.

Bjarne Stroustrup montre pour quelle raison il souhaite une notation concise, permettant des choses telles que void f(Sortable&); plutôt que template<class T> requires Sortable<T> void sort(T&); ou que template<Sortable T> void sort(T&); (car c'est un sujet de débat; cette forme mène à des irritants et à de la confusion dans certains cas). Il décrit ensuite les deux formes traditionnellement proposées de concepts, soit la forme « variable » et la forme « fonction ».

Bjarne Stroustrup suit avec un argumentaire en faveur d'une saine définition de concepts, soit s'astreindre à ne définir des concepts que lorsque ceux-ci décrivent une sémantique. En ce sens, Integral<T> est approprié à ses yeux, mais Incrementable<T> ne l'est pas.

Une discussion de requires requires... suit; cette séquence de jetons apparaît parfois avec l'acception des concepts dans la TS existante. Quelqu'un est d'accord sur le fait que c'est un passage perfectible, mais ne voit pas cela comme un obstacle insurmontable. La possibilté de surcharger les concepts est aussi discutée. Un plaidoyer pour le passage aux concepts s'ensuit, pour réduire le recours à des trucs comme enable_if et améliorer, dans l'ensemble, l'expérience de programmation.

Quelqu'un parle ensuite du Definition Checking, un dossier chaud car extrêmement complexe sur le plan du calcul. Il suggère de ne pas s'occuper de ce dossier dans l'immédiat, car trop de questions ouvertes demeurent.

Quelqu'un liste plusieurs exemples d'utilisation, puis décrit des espaces qu'il entrevoit pour améliorer le mécanisme tel que proposé : supprimer le mot bool dans les concepts, car ceux-ci sont toujours bool de toute manière; permettre d'ajouter des Expression Concepts; clarifier le sens de f(Iterator,Iterator) qui actuellement est différent de f(auto,auto) (le premier exige le même type aux deux endroits, mais pas le second).

Plusieurs estiment que nous devrions accepter les concepts dès C++ 17. À son avis, ils sont prêts.

Quelqu'un demande s'il est opportun de poser des questions techniques; on convient que oui, mais tant qu'on reste sur le fond du débat. Quelqu'un se demande si, en expérimentant avec les concepts, apposer un concept trop restrictif sur les paramètres d'une fonction bloquera le code client qui cherchera à l'utiliser, et quelqu'un confirme que c'est le cas, sans égard à la définition de la fonction. C'est une bonne chose, en fait; bien mieux qu'une erreur à l'exécution. Quelqu'un trace un lien avec les contrats, qui son l'un des ses sujets d'intérêt personnels.

P0587R0 – Concepts Revisited

Richard Smith présente sa réponse à la rétroaction de ses usagers sur la base de la TS sur les concepts. Il compte couvrir la syntaxe, l'équivalence entre concepts, le problème de l'ordonnancement partiel des concepts et la définition des fonctions génériques.

Pour ce qui est de la syntaxe, Richard Smith propose d'unifier les deux syntaxes existantes (variable et fonction) en une seule, et d'en faire un concept (!) de première classe du langage. Il estime que ce virage syntaxique allégerait leur utilisation, et réduirait les risques de surcharge accidentelle dans le cas de fonctions (Richard Smith propose d'unifier les syntaxes sur la base de la notation de variable). Quelqu'un signale que leur feedback usager n'a pas montré d'utilisation concrète de la surcharge de concepts. Quelqu'un est aussi d'avis qu'on pourrait aller dans cette direction. Quelqu'un a par contre des cas où ses concepts reposent sur des typedef assez lourds, et dit apprécier les fonctions pour cette raison. Quelqu'un dit vouloir les concepts, avec ou sans les ajustements, et souhaite qu'on garde les portes ouvertes. Quelqu'un se demande quelle est la raison pour souhaiter éliminer une des deux syntaxes; quelqu'un y voit plus de « contre » que de « pour », du fait que ça ne sert que peu en pratique et que ça crée des ambiguïtés.

Les équivalences sont un problème de fond, dont on discutait déjà à ma première participation au WG21 à Lenexa, en 2015 (et sans doute avant), soit le fait que deux concepts ne sont équivalents que s'il sont écrits exactement de la même manière, jeton pour jeton (donc template<class T> void f() requires T()==0&&true et  template<class T> void f() requires T()==0x00 sont distincts), et il y a une infinité de cas comme celui-ci (par exemple, (A&&B)&&C n'est pas équivalent à A&&(B&&C) dans une clause requires, et il en va de même pour typename T::template X<I> et typename T::template X<I+0>). Ceci implique que reformuler un concept existant brise le code client, même si les deux versions sont logiquement équivalentes. Quelqu'un pense que raffiner un concept, pour cette raison, devrait demander un acte explicite, et propose aussi de contraindre ce qu'un usager peut exprimer pour définir des relations de spécialisation entre concepts. Des questions de la salle permettent de clarifier la distinction entre équivalentes et fonctionnellement équivalentes. Quelqu'un pense que ce problème sera réglé par l'avènement des modules, et ne pense pas que les contraintes proposées par la proposition soient le chemin à suivre. Quelqu'un pense que l'exemple où I et I+0 montre que nous devons raffiner ce qui devrait être une forme normale dans le cas de la représentation d'une expression générique; il souhaite qu'on migre vers une représentation symbolique et sémantique plutôt que sur celle basée sur une soupe de jetons.

Quelqu'un se demande si toutes les réécritures de forme longue vers forme courte sont raisonnables, et pense que la version longue peut apparaître dans une interface alors que la courte peut suffire dans une implémentation, à titre d'exemple. Quelqu'un se dit frileux face à des hiérarchies de concepts, et parle du cas où deux vendeurs livreraient leur propre vision basée-concepts des itérateurs. Quelqu'un dit que la vision traditionnelle rend dans ce cas le code fragile. Quelqu'un rappelle une vieille discussion à l'effet que 2+2 et 4 étaient égaux ou pas dans le design des templates, et pense que les solutions de l'époque peuvent nous aider aujourd'hui. Quelqu'un dit que CWG a une liste publique de dossiers posant problème, sur la base de rétroaction venant des usagers. Quelqu'un dit que 2+2 est résolvable, clairement, mais qu'il faut un algorithme dans le standard pour éviter les réécritures divergentes d'une implémentation à l'autre.

Quelqu'un dit comprendre les deux positions sur les hiérarchies de concepts. Il mentionne qu'on peut se trouver face à une situation où deux compilateurs généreront par exemple un appel au constructeur de copie sur deux classes disjointes parce que ce sont « des classes pareilles l'une à l'autre, sauf pour le nom », et trouve cela indésirable. Quelqu'un pense que cette question pourrait être dans les Issues List pour discussion future, sans empêcher l'introduction des concepts dans le standard. Il suggère aussi de commencer avec des restrictions plus draconiennes, plus rigides, quitte à relâcher le tout ultérieurement (ce qui est plus facile à faire que l'inverse). Quelqu'un clarifie ce qu'il entend par hiérarchie de concepts.

Quelqu'un affirme que l'on dit vrai sur la question du problème entre équivalence et équivalence fonctionnelle. Il s'est avéré difficile d'implémenter les concepts sur au moins deux plateformes pour cette raison. La réécriture manuelle dans une forme courte pose aussi problème pour cette raison, car cela exige que la programmeuse ou le programmeur comprenne la réécriture réalisée par son compilateur. Quelqu'un souligne plusieurs contradictions dans le discours de plusieurs intervenants; il rejoint ceux qui estiment qu'il y a un problème avec l'équivalence fonctionnelle exprimée sur une base syntaxique, ce qui est incorrect à ses yeux et ne rejoint pas le design initial. Bjarne Stroustrup et Richard Smith sont en fait d'accord sur le fond; leur différend semble découler d'une lecture différente du texte.

Brève pause versh 55. Quelques factoïdes disparates :

On reprend les travaux vers 10 h 15.

Richard Smith poursuit sa présentation. Il montre comment décrire des relations de subsomption pour éviter de faire reposer l'équivalence fonctionnelle sur une équivalence syntaxique. Quelqu'un souligne un problème possible en pratique avec l'approche proposée. Quelqu'un pense que le problème à adresser est réel, mais que la solution proposée peut causer de nouveaux problèmes, pires que la maladie que le remède cherche à adresser. Les discussions qui s'ensuivent ne montrent pas clairement la supériorité d'une approche ou de l'autre, à mon avis. Quelqu'un fait valoir que la subsomption n'est pertinente que dans le cas où l'ordonnancement partiel des concepts intervient; à son avis, ce qui est proposé ici ne devrait pas mener à une controverse; il met aussi de l'avant que cette approche décourage les cas de requires requires qui agacent les gens. Quelqu'un dit nettement préférer ce qu'il comprend de la présentation que ce qu'il avait compris sur la base du seul texte.

Quelqu'un comprend le gain obtenu en évitant de faire dépendre l'équivalence fonctionnelle sur des jetons, mais pense que la nouvelle préoccupation fera dépendre le code résultant de la factorisation des concepts en sous-concepts (au sens où deux décompositions distinctes deviendraient équivalentes ou pas). Quelqu'un en parle comme un cas de packaging de concepts, et pense qu'on a fait un pas en avant; il en profite pour circonscrire le cas, un peu niche maintenant, où le problème surviendrait.

Quelqu'un demande à Andrew Sutton les raisons du design original. Andrew Sutton invoque le cinquième amendement  . Quelqu'un rappelle que deux écritures identiques peuvent porter des sémantiques distinctes en pratique. Quelqu'un explique les conséquences. Quelqu'un souligne l'impact de l'ordonnancement des jetons dans la proposition traditionnelle; les gens dans la salle sont partagés sur l'aspect positif ou négatif de cet impact. Quelqu'un rappelle qu'il ne faut pas voir les noms de concepts comme des alias; ce n'est pas le sens que cette chose doit porter.

La question d'un programme consommant des concepts connexes de bibliothèques A et B survient. Quelqu'un ne pense pas que ce genre de code sera brisé; il pense toutefois qu'il ne faudrait pas que le changement proposé brise la capacité de surcharger les fonctions, mais n'est pas d'avis que le code client sera réellement impacté. Quelqu'un souligne que l'ambiguïté est la meilleure solution quand le code est ambigü. Quelqu'un suggère de passer par une disambiguation à travers les noms de namespace, mais cela ne corrigera pas la situation.

Quelqu'un dit préférer, pour les concepts, des exemples concrets plus que des exemples abstrait. Quelqu'un demande si les règles mises de l'avant fonctionneraient aussi avec des traits. Semble que ce soit l'intention.

Quelqu'un amène la question des points de personnalisation. On sait comment faire avec des traits, en utilisant enable_if et des déclarations a priori, mais présentement il n'existe pas de déclaration a priori des concepts. Cela introduit une dépendance physique entre les fichiers. Quelqu'un explique que c'est parce qu'il est nécessaire de connaître l'implémentation des concepts pour résoudre les relations de subsomption. Quelqu'un fait remarquer que la proposition ne permet pas d'exprimer des spécialisations plus pointues d'un concept plus général. Quelqu'un constate que les concepts deviennent plus quelque chose comme des axiomes; plusieurs (pas tous) pensent que c'est une bonne chose.

Ville Voutilainen ouvre la porte pour un vote, maintenant ou plus tard. Quelqu'un pense qu'un vote directionnel serait pertinent. Quelqu'un pense qu'il faudrait plus en faire un Issue et y réfléchir. Quelqu'un serait à l'aise qu'on lui demande plus d'exemples et l'encourage à poursuivre. Quelqu'un propose un exemple : cowboy.draw() et shape.draw(). En POO, ce n'est pas un problème, mais en programmation générique, c'est une autre histoire. Ce qu'on veut selon lui est continuer de permettre le Duck Typing statique. Quelqu'un ajoute une fonction execute() (on rit un peu) qui appellerait draw(), mais avec des contraintes distinctes (draw() et shoot() pour un cowboy). Traditionnellement, ça aurait passé; lui pense que ça devrait être ambigü. Quelqu'un pense au contraire que le meilleur match devrait être choisi, et que le code ne devrait pas être ambigü. On fait remarquer que si shoot() est requis, alors il n'y a pas d'ambiguïté. Quelqu'un trace une distinction entre satisfaire deux concepts et avoir un lien entre ces concepts. Quelqu'un souhaite avoir ces exemples par écrit (merci!). Quelqu'un rappelle que les discussions sur le hijacking de mécanismes que nous avons aujourd'hui rappellent celles de l'époque où la proposition de surcharger operator+() a étéa été tenue. Quelqu'un rappelle que lors d'une ambiguïté, les expressions ambiguës sont supprimées du Overload Set (vive SFINAE).

Quelqu'un indique que les opérateurs && et || sont, pour fins de subsomption, de complexité exponentielle (en fait, c'est une complexité quadratique d'une complexité exponentielle... Ouch!). Le vrai problème, en pratique, est les || en fait, car template<class T> concept bool C=A<T>||B<T> signifie que A<T> et B<T> subsument C<T>. On voit des cas semblables dans des trucs aussi communs que less<T>, qui sert par défaut dans les conteneurs associatifs. Il estime que les deux options sont de l'interdire, en apposant des limites pratiques d'implémentations, ou de rendre la subsomption explicite, ou de supprimer l'ordonnancement partiel sur la base de ||. Quelqu'un indique qu'une seule disjonction peut faire dégénérer la complexité de l'évaluation du concept. Quelqu'un demande quelle est la gravité pratique du problème. Quelqu'un explicite quel est le pire cas; le cas moyen, avec les règles traditionnelles, est plus raisonnable. Quelqu'un pense que plus d'exemples serait utile. On demande si un usager devrait « rouler » un algorithme sur son propre code pour comprendre les impacts de ses concepts; présentement, on rit un peu mais la réponse serait affirmative. Cela dit, c'est un problème connexe à celui des règles de surcharge, et celles existantes sont déjà mal comprises de la majorité. Quelqu'un dit que la version originale de l'implémentation avec gcc réalisait l'algorithme qui mène au pire cas, et que leur implémentation a été modifiée depuis. Quelqu'un clarifie le fait que les disjonctions sont « cachées » dans un concept nommé et deviennent un concept atomique.

Ville Voutilainen indique qu'il faudra poursuivre cet après-midi, la question n'étant pas épuisée. Herb Sutter valide l'intérêt de la salle pour poursuivre en grand groupe; c'est le cas.

On prend la pause à 11 h 30. Ce fut un matin productif. Il y a encore des chocs de culture, surtout pour ce qui touche à la question de la langue utilisée (la langue des implémenteurs de compilateurs est différente de la langue des idéateurs de nouveeaux mécanismes). Il y a du travail à faire sur ce point.

J'ai fait un peu de correction, puis constatant que le temps filait, je suis allé me chercher un sandwich. Au retour, j'ai eu la chance de « piquer une petite jasette » avec Hans Boehm à propos des travaux de SG1. J'en ai profité pour mieux comprendre les enjeux associés aux atomic<float>, et lui à mieux comprendre pourquoi une part signficiative des entreprises de haute technologie ne fait que commencer à toucher à C++ 11 alors que C++ 14 sera bientôt « remplacé » (façon de parler, bien sûr) par C++ 17.

À mon retour dans la salle de travail d'EWG, j'ai pu bavarder avec Jean-Christian van Winkel à propos de la séance de soirée de jeudi soir, où nous discuterons de vision. On a discuté de diversité, d'ouverture, de mixité d'âge, de culture, de genres, et bien sûr de vocabulaire pour mieux se comprendre même entre experts. Il m'a dit apprécier les présentations comme celle de Bjarne Stroustrup ce matin, qui mettent d'avant les grands principes à chaque étape; je suis plutôt d'accord avec lui, bien que  je ne pense pas que ce soit les principes qui accrochent tant que leur opérationnalisation. C'est peut-être la complexité de cette bête que nous domptons ici, ce langage immense, qui fait que le fossé de vocabulaire se creuse entre les gens qui réalisent le langage, développent et entretiennent les compilateurs, et les idéateurs du langage, qui amènent du neuf au moulin mais l'expriment d'une manière générale, par des principes, et ne se reconnaissent pas toujours dans les mots par lesquels leurs idées finissent par prendre forme.

On reprend vers 13 h 15. Les gens sont ici depuis longtemps, mais il y a du travail en coulisses pour faciliter la connexions des idées.

Richard Smith reprend sa présentation. Il démontre des cas d'ambiguïté avec les constrained function template definitions, qui laissent transparaître des nouvelles sources de bogues obscurs. Par exemple :

template <class T, class ... U>
   concept bool Constructible = requires (U...u) { T(u...) };
// ensuite, Constructible<X, int> peut vouloir dire plusieurs trucs distincts

On a aussi le cas de la notation concise, f(It a,It b), où il n'est plus clair si a et b doivent être du même type ou pas. Ou le cas template<int A, X<int> B> qui a un sens différent selon le rôle de X en tant que concept ou pas. Quelqu'un suggère une syntaxe pour lever ces ambiguïtés, soit f(InputIterator T x,T y) qui dit que x est un itérateur de T et y un T, ou f(InputIterator auto x,InputIterator auto y) qui dit que les deux sont des InputIterator sans les contraindre à itérer sur un type commun. Quelqu'un demande des précisions sur le problème. Quelqu'un souligne que le problème est réel, mais qu'on a plusieurs propositions pour les adresser; il suggère que les proposeurs se rencontrent en petit groupe pour avoir un consensus préalable.

Quelqu'un dit avoir eu une réaction négative au préalable avec la syntaxe concise, mais l'avoir beaucoup apprécié à l'usage. Une fois que l'on accepte qu'on n'a pas tant un type qu'une contrainte sur une valeur, l'usage devient plaisant. Quelqu'un fait remarquer que la proposition sur la table est requise pour un concept sur un type mais ne le serait pas pour un concept sur une valeur. Quelqu'un souhaite que l'on retienne qu'il y a deux problèmes distincts ici, même s'il est possible qu'une même solution pour les deux soit possible. Quelqu'un fait remarquer (à juste titre) que, comme les concepts, un type est une contrainte sur des valeurs.

Quelqu'un demande que l'on réfléchisse à ce qui suit, car la même syntaxe décrit deux réalités :

template <int A, X<int> B> // A est int, B est un type qui satisfait int
void f(int A, X<int> B); // A est int, B est une valeur d'un type satisfaisait X<int>

Quelqu'un recommande le recours à des exemples concrets. Quelqu'un revient sur la distinction entre les concepts sur les types et les concepts sur les valeurs. Il faut selon lui être capable de matérialiser un concept sur un type dans un concept sur une valeur. Quelqu'un cherche à savoir comment on pourrait exprimer dans le premier cas ce qu'on exprime dans le deuxième cas. Quelqu'un dit que ce n'est pas possible, du moins pas avec la forme concise (ça se fait avec la forme longue). Quelqu'un rappelle que la forme courte est un outil, pas une panacée. Quelqu'un revient sur la question posée sur la cohérence des deux formes; il pense que c'est l'introduction des paramètres auto en tant que concepts les plus généraux qui sont la racine du problème. Quelqu'un n'est pas en désaccord, bien que l'incohérence demeure réelle à ses yeux. Quelqu'un a l'impression qu'on discute d'un cas niche en parlant de contraintes sur un non-type template parameter. Quelqu'un mentionne que ça survient avec auto. Quelqu'un pense que le cas étrange devrait exiger un peu de syntaxe supplémentaire, et que le cas général ne devrait pas l'exiger. Quelqu'un fait remarquer que requires est précisément cette syntaxe supplémentaire. Quelqu'un souhaite une syntaxe plus cohérente, et dit qu'on peut exiger typename pour les cas qui en ont besoin. Quelqu'un suggère de ne pas y toucher et d'utiliser la forme longue quand le besoin survient. Quelqu'un abonde dans le même sens. Quelqu'un espère que pour les usagers, le nom du concept sera suffisamment clair pour éviter toute confusion chez les usagers. Quelqu'un dit que dans son expérience, après avoir écrit une bibliothèque complète utilisant des concepts et consommée par plusieurs programmes, le problème n'a jamais été signalé. Une expérience avec des étudiant(e)s, relatée par un participant, va dans le même sens.

Quelqu'un pense qu'on peut continuer d'explorer la question mais estime que ça ne devrait pas bloquer l'acceptation du mécanisme. Quelqu'un est d'accord qu'aucune des préoccupations prises individuellement ne devrait bloquer l'acceptation du mécanisme, mais que l'accumulation de préoccupations lui semble suffisante pour que le travail se poursuive.

Ville Voutilainen demande si l'assemblée est prête pour un vote directif. Daveed Vandevoorde dit qu'il apprécierait faire sa présentation au préalable.

Terse Syntax Alternative

Daveed Vandevoorde suggère de clarifier le fait que X soit un concept un écrivant <X>, et que f(<X> a,<X> b) devrait signifier que a et b sont du même type (sinon, utilisez la syntaxe longue). Il est conscient que auto est un cas particulier. Dans sa vision, [](auto x,auto y){} permettrait x et y d'avoir deux types distincts alors que [](<typename> x,<typename> y) ferait en sorte de leur donner le même type. Quelqu'un dit que ça va selon lui rassurer les gens au début et les faire sacrer après un bout de temps car ils trouveront que la syntaxe est de trop une fois leurs repères bien situés. Quelqu'un fait remarquer que la proposition rend même la syntaxe des templates plus concise. Quelqu'un dit que ce dont il a besoin quand il appelle une fonction générique est de connaître la sémantique associée aux types, plus que savoir quels types sont génériques. Quelqu'un dit voir à cette proposition l'avantage que la syntaxe concise générée apporte, mais avoir un désaccord sur les raisons. Quelqu'un dans la salle dit apprécier la cohérence de la syntaxe proposée. Quelqu'un dit que dans sa bibliothèque, auto aurait pu être utilisé pour les paramètres, mais que Callable<T> était plus clair; il craint que l'ajout de chevrons amène les gens à utiliser auto tout simplement.

Quelqu'un remarque qu'il est facile d'en arriver, avec la syntaxe concise, à une utilisation plus verbeuse qu'avec la syntaxe longue. C'est une conséquence d'écrire void f(InputIterator,InputIterator); plutôt que template<InputIterator T> void f(T,T); en pratique. Quelqu'un dit regretter le terme Terse Syntax, qui était mal choisi quand on examiner a posteriori ce qui en est fait. Quelqu'un pense que pour les gens qui entretiennent le code, c'est très important de savoir si un nom est un template ou un concept; pour eux, la syntaxe concise est un irritant. Quelques échanges un peu musclés s'ensuivent; le sujet est sensible. Quelqu'un demande si cette syntaxe fonctionne aussi avec Callable<int>, et où placer les chevrons. Quelqu'un fait mention que l'ajout d'une telle syntaxe n'impose à personne de l'utiliser; ça ne fait pas de mal à ses yeux. Quelqu'un indique que les nouveaux mécanismes syntaxiques ajoutés au langage doivent être intégrés en tenant compte des outils modernes, par exemple la coloration du code. Quelqu'un pense qu'alléger l'écriture est le chemin à suivre pour C++, et ne voit pas la proposition comme un allègement.

Quelqu'un pense que l'idéal est d'avoir des syntaxes distinctes pour des idées distinctes. Quelqu'un pense que c'est particulièrement vrai quand les différences importent. Quelqu'un dit que le débat qui manque porte sur le fond : vaut-il la peine de distinguer visuellement le code générique du code qui ne l'est pas. Quelqu'un pense que ça a été discuté : il y a une différence par exemple entre prendre l'adresse d'une fonction normale ou d'une fonction générique (mais c'est un problème qui existe avec la surcharge de fonctions, et on n'en fait pas un plat). Quelqu'un mentionne que la syntaxe de base, template<Iterator I> I f(I,I) lui semble la plus claire. Quelqu'un rappelle le choix d'enlever le préfixe struct devant les variables de type struct, s'éloignant de la tradition C, qui avait causé des remous à l'époque. Quelqu'un rappelle une forte différence sémantique entre une surcharge de fonction ou une méthode virtuelle et une fonction générique. Quelqu'un ajoute que l'attention aux détails dans l'implémentation de ces deux familles de cas est fort différente.

Quelqu'un propose un vote surprenant : intègre-t-on le TS sur les concepts dans le IS, pour ensuite régler les irritants. Le libellé ne dit pas quand faire la fusion. Plusieurs demandent si on vise C++ 17. La réponse est est non. Certains pensent que ça va accélérer les travaux sur les concepts pour C++ 20. D'autres craignent que cela n'envoie le mauvais message à des gens qui ne participent pas aux travaux du WG21, en leur laissant croire que nous ne changerons rien. Certains rappellent que l'on a encore plusieurs débats de fond et plusieurs changements à faire, recommandant une approche plus conservatrice. Quelqu'un demande que l'on puisse continuer à faire des Breaking Changes aux concepts même s'ils sont fusionnés au IS, ce qui est confirmé. Certains mentionnent notre responsabilité collective de publiciser le fait que les concepts, même dans le IS, vont changer d'ici C++ 20. Certains expriment la conviction qu'une insertion dans le IS accroîtra la quantité de rétroaction que nous obtiendrons. D'autres sont au contraire d'avis que ce geste aura au contraire l'effet d'endommager le processus des TS. Certains estiment que le TS existant a déjà été modifié et a fait des progrès, et sont donc d'avis que le processus ne sera pas entaché par un vote favorable. Quelqu'un rappelle le précédent de <filesystem> (mais quelqu'un demande qu'on évite d'intégrer de refaire comme pour <filesystem> à l'avenir, car LWG travaille comme des fous cette semaine pour finaliser les multiples NB Comments associés à ce dossier). Le fait que pouvoir entretenir les concepts dans un TS est plus simple que dans un IS est relevé, car le nombre de ramifications à chaque changement est plus petit. Quelqu'un rappelle que dans le cas des concepts, nous avons certains NB Comments à traiter qui remontent à plus de deux ans déjà et n'ont jamais été traités. Le fait que EWG et CWG travaillent ensemble aujourd'hui est mis de l'avant.

Le vote est tenu. Nous n'avons pas de consensus (ça ressemble à une courbe normale inversée, ce qui exprime bien la polarité des opinions).

Un autre vote est ensuite tenu, à savoir si l'on devrait (de manière obligatoire) distinguer visuellement le code générique du code qui ne l'est pas dans la notation concise. Certains disent ne pas aimer la forme concise du tout, mais on leur rappelle l'existence d'une telle forme dans le TS alors c'est une préoccupation distincte.

Le vote est tenu. Nous n'avons pas de consensus  Cette fois, ça ressemble à une courbe normale aplatie.

Quelqu'un suggère qu'on donne du temps pour que les proposeurs se réunissent et discutent un peu. On demande tout de même une orientation de la part du comité sur l'approche unifiant les syntaxes de variable et de fonction pour les concepts. Quelques échanges s'ensuivent, car des gens ont découvert les différences aujourd'hui et ne sont pas sûrs de vouloir voter.

Deux votes sont à tenir, soit examiner l'opportunité de supprimer la distinction entre concept variable et concept fonction, et examiner l'opportunité de se débarrasser du mot bool. Le consensus est atteint dans les deux cas.

Deux autres votes sont tenus, à propos de la restriction de redéclarations de concepts à des formes identiques, et pour faire en sorte que l'équivalence fonctionnelle ne dépende pas d'une même séquence de jetons.

Le premier vote obtient le consensus. Le second vote obtient aussi le consensus. Pour le second, en particulier, je suis heureux car ça m'agaçait depuis le tout début.

Quelqu'un suggère un autre vote, un peu tardif, par lequel nous inclurions le TS dans le IS dès que les Issues associés à la syntaxe concise seraient réglées.

On prend une pause vers 15 h 20. J'ai un échange avec John Lakos sur le sens de l'un des votes, car nous n'avons pas compris la même chose du résultat du vote; il va vérifier auprès de Richard Smith pour voir ce qu'il en est, puisque le vote était basé sur sa présentation... et même après vérification, nous n'avons toujours pas compris la même chose. Je ne pense pas qu'on soit particulièrement bêtes, ni l'un ni l'autre, alors je pense que la valeur du vote devra être reconsidérée 

On se déplace dans la pièce de CWG pour reprendre nos activités normales. On bavarde pendant la pause (où tout le monde est sur place pour travailler, parce que CWG, c'est un peu comme ça) sur la frontière entre le Canada et les États-Unis et les nouvelles pratiques dans un sens comme dans l'autre depuis novembre 2016. L'autre sujet de blagues est mon laptop qui ne cesse de faire du bruit; j'espère sincèrement parvenir à régler ce problème avant la rencontre de Toronto.

Mike Miller annonce la reprise des travaux. Il est 15 h 45. On abordera la terminologie pour les Deduction Guides en vue de C++ 17.

Drafting for class template argument deduction issues

On examine la proposition terminologique mise de l'avant par Jason Merrill.

Quelqu'un suggère d'élargir une phrase qui ne couvre que le constructeur par défaut de manière à rejoindre l'ensemble des constructeurs rédigés par le code client.

Quelqu'un appporte de nouveaux exemples, par exemple :

template <class T> struct A {
   A(T); // #1
   A(const A&); // #2
};
template <class T> A(T) -> A<T>;  // #3, less specialized than #2

A a (42); // uses #3 to deduce A<int> and #1 to initialize
A b = a;  // uses #2 to deduce A<int> and initialize

template <class T> A(A<T>) -> A<A<T>>;  // #4, as specialized as #2

A b2 = a;  // uses #4 to deduce A<A<int>> and #1 to initialize

Quelqu'un fait remarquer l'omission d'un cas dans les règles (celui où il n'existe pas de primary class template). On examine l'intérêt de l'ajouter. Quelqu'un fait remarquer que dans le cas d'une classe vide, on génère le guide implicite pour le constructeur de copie. Quelqu'un suggère que l'existence de deux guides générant un même type et menant à une résolution ambiguë, on pourrait simplement déduire le type que les deux guides génèrent plutôt que d'échouer la déduction. C'est inhabituel pour la résolution des ambiguïtés, mais ça semble fonctionner pour ce mécanisme.

Quelqu'un se demande s'il ne serait pas pertinent d'offrir un exemple des conséquences du mot clé explicit sur les guides de déduction; il craint que les gens ne confondent ces guides avec les constructeurs explicites de la classe déduite, alors que l'un n'implique pas l'autre. Quelqu'un rappelle l'impact des guides explicites, particulièrement dans le cas du list initialization.

Quelqu'un dit que LWG se questionne sur un cas un peu compliqué, soit la déduction d'un vector<size_t> qui requiert l'ajout de guides explicites supplémentaires. On discute de l'ajout d'un exemple pour montrer que ça fonctionne et comment y arriver.

Quelqu'un souligne au passage que Core Issue 2 (qui n'est pas encore fermée) est assigné à John Spicer. On se bidonne un peu.

Quelqu'un dit qu'il existe d'autres situations que les simple declarations qui sont connexes et devraient être couvertes dans la terminologie.

Quelqu'un pense que tôt ou tard, nous aurons besoin d'un = delete pour ce mécanisme, ou de quelque chose de connexe pour supprimer certaines surcharges. Quelqu'un dit être conscient du besoin, mais n'est pas sûr de la meilleure expression pour ce mécanisme. Quelqu'un propose une approche technique existant dans le langage déjà. Quelqu'un pense que = delete dans sa forme actuelle (en fait, ça n'existe pas pour C++ 17, mais on lui a dit que ce pourrait être un DR, ce pour quoi la salle est plus froide – c'est de la nouvelle syntaxe, après tout) serait déjà utile pour supprimer, par exemple, la déduction d'un valarray<T> à partir d'un T*. Quelqu'un pense que dans le cas où le code client contient des constructeurs qui ne « mappent » pas élégamment au substrat modélisé, on risque de générer du code insensé. Quelqu'un fait remarquer que son banc d'essai était la bibliothèque standard, qui est dans l'ensemble plutôt bien conçue sur ce plan, mais ajoute que le mécanisme n'est pas obligatoire pour qui n'en veut pas.

GB66 – Replacing sized delete

Le problème souligné tient au cas où il n'est pas clair s'il faut privilégier la version de operator delete recevant une taille en paramètre et celle n'en recevant pas, dans le cas où l'un des deux a été surchargé mais pas l'autre. L'exemple proposé pour illustrer le propos semble simple, mais amène des questions :

void operator delete(void*) noexcept; // #1
// void operator delete(void*, std::size_t) noexcept; #2
void f() {
  int * p = new int(42);
  delete p;    // calls user-declared #1 or built-in #2
}

Quelqu'un nous amène à §18.6.2.1 p. 16, qui indique que par défaut, le code qui accepte une taille relaiera simplement l'appel à la version qui n'en accepte pas, pour faciliter la transition. On relaie l'information à l'originateur du commentaire pour voir si nous avons bien compris sa remarque.

On discute d'un cas problématique de placement new mal foutu décrit à §5.3.4 p. 23. Quelqu'un ne pense pas que ce soit le cas qui ait donné naissance à GB66.

On reviendra sur cette question quand nous en saurons plus.


Quelqu'un revient sur le cas un peu particulier des guides de déduction pour unique_ptr, §20.11.1.2. Quelqu'un pense que la terminologie existante ne permet pas de déduire le type à générer pour le moment. Faudra rendre la terminologie plus spécifique que using pointer = see below, qui n'est pas du C++ et ne dit pas comment réaliser la déduction, ou si même elle est possible.

Jason Merrill nous présente une nouvelle version de la terminologie.

Quelqu'un fait remarquer que la terminologie proposée, « If a placeholder for a deduced class type appears as a decl-specifier in the decl-specifier-seq of a variable declaration (including e.g. a condition (6.4), for-range-declaration (6.5.4), or static data member (9.2.3.2)) , the placeholder is replaced by the return type of the function selected by overload resolution for class template deduction (13.3.1.8). » ouvrirait la porte à la déduction des paramètres génériques des fonctions, un mécanisme involontaire et pas nécessairement désirable (le terme « variable declaration » est trop fort).

On retravaille la formule pour réduire la portée de ce qui peut être fait. Le même passage est reformulé comme « If a placeholder for a deduced class type appears as a decl-specifier in the decl-specifier-seq of a variable definition (including e.g. a condition (6.4) or for-range-declaration (6.5.4)), or of a static data member declaration with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.2.3.2)) , the placeholder is replaced by the return type of the function selected by overload resolution for class template deduction (13.3.1.8). », ce qui est plus contraignant.

Reste la question de deux guides générant le même type sur la base de déductions ambiguës. Quelqu'un suggère qu'il faille d'abord produire un exemple concret avant de formuler une terminologie. On semble d'accord avec cette position. Quelqu'un esquisse une direction susceptible de nous mener à une telle situation. On penche pour traiter ça dans un DR, le cas échéant.

Quelqu'un parle d'un autre cas de DR possible, du fait que nous générons en fait des constructeurs génériques avec ce nouveau mécanisme, ce qui peut générer des surprises.

Quelqu'un identifie un autre cas possible de problème avec la formulation existante. On va prendre le temps d'exprimer une liste exhaustive des cas possibles, ce qui devrait régler le problème. On y reviendra.

Je me suis pris une bière (un peu moins chère, car c'était le Happy Hour de l'hôtel, mais chère tout de même), puis je suis allé à ma chambre parler un peu à Za et à Marguerite qui était à la maison (semble qu'elle viendra me cueillir à l'aéroport lors de mon retour dimanche, avec mon pus jeune Ludo, ce qui est bien chouette de sa part). Sur le chemin, j'ai croisé Paul Preney, un nouveau membre de la délégation canadienne, qui semble bien sympathique. Je vais essayer d'aller manger une bouchée avec lui cette semaine, question de faire un peu sa connaissance.

J'ai travaillé un peu, je suis allé me chercher un plat de nouilles non-loin, j'ai travaillé encore un peu par la suite, mais je me suis endormi tôt, encore une fois vers 20 h. Le décalage horaire, le stress et les journées de travail très lourdes ont eu raison de moi cette fois.

Jour 2 1er mars 2017

Debout versh, pour compenser mon sommeil hâtif de la veille et préparer la journée. Lectures, douche, j'écoute un peu la radio de Radio-Canada grâce à Internet (et je reste chaque fois stupéfait que les émissions de télévision, elles, soient bloquées, même si je n'en regarde que vraiment très peu). J'entends entre autres Judith Lussier, qui dit avoir abandonné son rôle de chroniqueuse car c'était devenu trop difficile (harcèlement, pression, menaces et autres idioties), puis Nabila Ben Youssef qui a quitté le Québec parce qu'elle s'y sentait moins libre qu'auparavant (on parle d'une humoriste qui a pris des positions pour la laïcité pendant les remous des dernières années) et je me sens bien triste tout à coup. Le vivre ensemble a beaucoup souffert chez nous ces dernières années.

Plusieurs lectures (je vais finir par reprendre le dessus), dont celle d'une proposition que je dois défendre en après-midi et que je n'avais pas bien intégré encore. Je me suis aussi joint à un groupe de discussions sur Slack, un outil de clavardage particulier dans lequel on trouve un groupe spécifiquement destiné au langage C++, pour faciliter la communication avec les experts ici et celles / ceux qui ne peuvent pas se présenter aux rencontres du comité.

En marchant vers la salle de travail de CWG, j'ai croisé la toujours charmante Lisa Lippincott , avec qui j'ai bavardé de la météo (sujet inépuisable, mais honnêtement, c'est moins lourd cette semaine que je ne l'aurais cru : il y a un petit vent, c'est un peu gris aussi, alors rien d'écrasant), le sympathique Marshall Clow que j'ai remercié car LWG fait un travail colossal sur <filesystem> cette semaine, et le chic type dont le nom m'échappe qui m'a reconnu en début de semaine et qui m'a avoué lire ce que j'écris (c'est toujours étrange d'entendre ça), que ses collègues font de même, et avec qui j'ai bavardé des aléas de l'implémentation des exceptions.

Assis chez CWG, la bonne nouvelle du jour était que Kate Gregory (une très chic dame) semble avoir survécu à ce vilain cancer qui l'avait affligé. Gor Nishanov est passé nous saluer mais nous ne le verrons qu'un peu plus tard aujourd'hui. Ensuite, Bjarne Stroustrup et Gabriel Dos Reis sont venus se joindre à nous car nous discuterons des modules avec eux ce matin.

Ls travaux débutent versh 5. La salle est pleine.

D0583R0 – Modules: Contexts of Template Instantiations and Name Lookup

Le texte préparé par Gabriel Dos Reis couvre l'exemple discuté lundi. Des divers exemples présentés, Gabriel Dos Reis suggère qu'on en examine deux de plus près. Le premier est :

// X.h
namespace Q {
   struct X { };
}
// Module M1:
#include "X.h"
// global module
namespace Q {
   X operator+(X,X);
   // private implementation details
}
module M1;
export template<typename T>
   void g(T t) { t + Q::X{ }; }
void j(Q::X x) {
   g(x); // #1
}
// Module M2:
#include "X.h"
module M2;
import M1;
void h(Q::X x) {
   g(x);
   // #2
}

Cet exemple, selon lui, fonctionne tel qu'attendu. Le deuxième est plus délicat :

// Module A:
module A;
export template<typename T>
   void f(T t) { t + t; }
// Module B:
module B;
import A;
export template<typename T>
   void g(T t) { f(t); }
// Module C: (c'est l'interface dans ce cas) 
struct S { };
S operator+(S,S);
module C;
import B;
export template<typename T>
   void h(T t) {
      g( (t, S{ }) ); // argument is comma expression
   }
// Main translation unit:
import C;
void i() {
   h(0);
}

Quelqu'un décrit pas à pas le contexte d'instanciation des éléments clés, l'impact d'ADL, et les attentes envers les compilateurs. Quelqu'un s'interroge sur l'importance (ou pas) de placer operator+ dans le module global. Quelqu'un explique les règles dans ce cas. Quelqu'un pense qu'avec les règles proposées, une fonction générique appelant une fonction qui ne l'est pas interagirait de manière surprenante avec les règles traditionnelles de lookup. Quelqu'un pense qu'il faudra ajouter un petit quelque chose pour l'association entre types et namespace partitions; cette association est sous-entendue, mais la pratique dans le texte du standard est d'éviter les sous-entendus pour réduire les divergences de comportement des implémentations. La section §3.4.2 [basic.lookup.argdep] demandera un peu de travail en ce sens. On s'entend sur ce qui doit être fait.

Quelqu'un souligne que le texte ne rend pas clair le fait que l'on n'exporte pas automatiquement tout ce qui est dans le module global. Dans l'exemple, A forme decltype(declval<S>()+declval<S>()) mais rien ne rend évidente l'exporation de operator+(S,S) dans C. Déterminer en général ce qui doit être exposé, particulièrement avec un template, est un problème vraiment difficile à résoudre. Quelqu'un dit qu'il faudrait vraiment exporter operator+(S,S), mais on souligne que les règles existantes ne rendent pas simples l'exportation des symboles dans le module global. Quelqu'un note que ce qui apparaît dans le module d'interface doit être exposé dans une certaine mesure. Quelqu'un fait remarquer que ça peut devenir dispendieux si le module d'interface inclut des en-têtes lourds comme <windows.h>.

Sur le plan conceptuel, S n'appartient pas au module C ici; elle apparaît dans l'interface mais loge dans le module global. Il semble y avoir un besoin de clarification terminologique ici. Quelqu'un demande si l'exemple le plus récent est supposé fonctionner ou pas. Il y a un désaccord dans la salle. Quelqu'un dit que clang supporte cet exemple, même si la syntaxe est un peu différente de celle du TS actuel. Une des nuances entre les deux tient à ce qui est exporté ou pas de manière transitive par un module. Quelqu'un explique pourquoi les fichiers temporaires, dans les termes existants, seront immenses.

Le support possible des en-têtes précompilés (les fichiers .pch) entre dans les débats, mais certains ne sont pas convaincus de l'intérêt de tenir compte des .pch avec l'avènement des modules de toute manière. C'est une question pratique : des produits existants dépendent des .pch et ne pas les supporter entravera l'adoption du mécanisme. Certains sont d'avis que c'est un signe que le design, dans la décision de ne pas exporter ce qui apparaît dans le module global, est défectueux; selon eux, la solution est simplement de remplacer les .pch par des modules, justement. Quelqu'un rappelle l'audience à l'ordre, du fait que les .pch ne font pas partie du standard. Quelqu'un demande une clarification, que quelqu'un donne et que je ne répéterai pas ici, mais le problème devient limpide.

Un nouvel exemple est développé, sur la base du précédent :

#include <string>
import B;
module C;
export template <typename T>
  void f(T t) {
     g( (t, string{}) ); // operator comma
  }

Nathan Sidwell demande si cet exemple est supposé fonctionner, et nous convenons collectivement (majorité, pas unanimité) que ça devrait fonctionner (on n'a pas l'accord de tous que ça fonctionne avec le texte existant, cependant). Gabriel Dos Reis ajoute un détail :

export module A {
#include <string>
}
import B;
module C;
export template <typename T>
  void f(T t) {
     g( (t, string{}) ); // operator comma
  }

On parle de nouvelle syntaxe. Gabriel Dos Reis fait remarquer qu'il n'est pas clair, dans ce cas, quel comportement serait attendu. Le problème des gros fichiers intermédiaires tient en partie au recours à des fichiers d'en-tête, particulièrement dans l'interface; Richard Smith fait remarquer qu'il y a une solution simple, soit de les remplacer par des modules. Jonathan Caves explique la stratégie pour filtrer les importations redondantes, et le faire rapidement. On prend un vote sur notre perception que ça devrait, ou pas, fonctionner tel quel. C'est plutôt positif, mais partagé. John Spicer craint que l'ajout d'un bloc export module X{ /*...*/ } autour des inclusions n'amène les gens à mettre toutes leurs inclusions dans de tels blocs, par souci de simplicité.

Bjarne Stroustrup demande si le problème est significatif; Jonathan Caves dit que ça peut être considérable, car on fera payer les usagers massivement pour des trucs qu'ils n'utilisent pas. Bjarne Stroustrup fait remarquer que si ça ne fonctionne pas, il faut aussi leur expliquer pourquoi. Richard Smith note que dans l'implémentation de clang, la stratégie appliquée (qui passe par un fichier de configuration) escamote le problème; en retour, importer plusieurs modules qui ont inclus textuellement <string> impactera les temps de compilation, peu importe l'implémentation. John Spicer demande si un module MyHeaders incluant tous les en-têtes serait l'approche à privilégier. Richard Smith pense qu'un petit ajout syntaxique pour faciliter le filtrage des en-têtes serait préférable.

Mike Miller prend le relais et clarifie la nature des travaux à faire. Entre autres, il se demande s'il est possible d'aller de l'avant avec un PDTS et évaluer concrètement si le problème survient en pratique. John Spicer suggère que l'exemple discuté, et qui nous préoccupe, nous semble être un problème et que nous cherchons une solution. Bjarne Stroustrup rappelle l'importance d'avoir des exemples concrets (nous sommes toujours dans l'abstrait dans nos discussions, et il nous signale, avec justesse, que les usagers n'utilisent que peu des noms comme A, B ou C dans leurs programmes). Gabriel Dos Reis fait remarquer avec justesse qu'il ne sait pas comment exprimer ce souhait empirique dans un TS, du fait qu'on y trouve normalement du texte normatif, du texte non-normatif et des exemples. John Spicer indique que le coût est peut-être gérable du fait qu'il serait absorbé à la compilation de la définition d'un module, et qu'un module serait importé plus souvent qu'il est compilé.

Jens Maurer résume : on veut un ajustement à la section du standard pour ADL, tenant compte des namspace partitions; on veut les exemples 2 et 3 de la proposition dans le texte normatif, avec explications, pour mettre en relief l'effet des namespace partitions; on veut aussi l'exemple 4 dans le texte normatif avec une note expliquant qu'on veut que ça fonctionne (ça nous semble être un cas plausible) mais qu'on n'est pas certains de la meilleure manière d'y arriver.

Gabriel Dos Reis pense pouvoir revenir en après-midi avec une version à jour.

Drafting for class template argument deduction issues

Jason Merrill nous revient avec la version 11 du document. La principale mise à jour est l'introduction du terme grammatical initializing declaration. Le passage est « A declaration that specifies the initialization of a variable, whether from an explicit initializer or by default-initialization, is called the initializing declaration of that variable. In most cases this is the defining declaration (3.1) of the variable, but the initializing declaration of a non-inline static data member (9.2.3.2) can be the declaration within the class definition and not the definition at namespace scope. ». Richard Smith fait remarquer que ça pourrait éventuellement être utile pour clarifier la section sur auto, qui (incidemment) est un peu indigeste. Dinka Ranns suggère que la deuxième phrase soit une note non-normative, ce qui sied tout à fait; on remplace « can » par « might » au passage.

On ajoutera une puce pour spécifier les règles de désambiguation dans le cas des implicit deduction guides, dans l'optique de clarifier la marche à suivre dans un tel cas.

Petite pause versh 45. Je suis allé faire un tour chez EWG qui avaient des beignes à la cannelle (mioum!), j'ai parlé un peu avec Lisa Lippincott pour savoir comment la proposition par Herb Sutter sur la génération des opérateurs relationnels à partir d'un nouvel opérateur de comparaison tripartite (Three-Way Comparison) ayant la forme <=> a été reçue; il se trouve que c'est toujours en cours mais que ça lui semble très positif. Le sujet m'intéresse car j'ai fait partie des relecteurs de celle-là.

Chez CWG, on discute de divers dossiers ayant lieu ailleurs. J'entends le terme Heisensentence à propos d'une phrase dont le sens change selon l'angle de lecture, ce qui est adorable.

J'ai un courriel de Jonathan Wakely , que je vais probablement remplacer à Toronto en tant que secrétaire du comité, car il deviendra papa à une date proche de celle de la rencontre. Nous irons manger ensemble ce midi pour que je m'approprie les dossiers et les pratiques

On reprend le boulot.

GB66 – Replacing sized delete

Roger Orr dit avoir contacté l'auteur, et que ce dernier a confirmé que le bogue était de son côté, alors on parle d'un NAD.

Use "structured binding"

Jens Maurer propose une retouche terminologique pour remplacer le terme Decomposition Declaration par le terme Structured Binding Declaration, suivant les discussions avec EWG plus tôt cette semaine. Finalement, ça se lit assez bien et ça allège un peu l'écriture à un endroit.

Mike Miller suggère qu'on profite de l'opportunité pour ajouter un nom symbolique pour la nouvelle section. Richard Smith suggère [dcl.struct.bind]. Ça semble Ok. L'ancien nom symbolique prospectif était [dcl.decomp], mais il ne convient évidemment plus.

On convient d'en faire une proposition formelle vendredi plutôt qu'un correctif éditorial, du fait que c'était un point de discussion un peu contentieux.

P0270R2 – Removing C dependencies from signal handler wording

On examine cette mise à jour proposée par Hans Boehm . En gros, une fonction est signal-safe si elle n'appelle que des fonctions aussi signal-safe, si elle ne touche pas à de la mémoire thread_local, si elle ne lève pas d'exception et si elle n'a pas recours à l'initialisation dynamique d'une variable statique. Contrevenir à ces règles nous amène dans une zone de comportement indéfini.

Richard Smith se questionne à savoir si dynamic_cast sur des pointeurs est considéré signal-safe; nous ne sommes pas certains si dynamic_cast a le droit d'allouer de la mémoire. Jens Maurer pense que cela ouvrirait la porte à lever un truc comme bad_alloc, ce qui ne lui semble pas permis, mais c'est pas automatiquement évident.

Hubert Tong suggère qu'être signal-safe puisse dépendre de l'instanciation ou de l'utilisation, donc qu'une fonction puisse être signal-safe si elle ne passe pas par telle ou telle branche.

Hubert Tong pense aussi que dynamic_cast peut poser problème, du fait que certaines implémentations peuvent conserver une Cache des résultats. On pense interdire ce mécanisme dans une fonction signal-safe. On examine les implémentations existantes, on contacte Billy O'Neal pour savoir ce que fait l'implémentation de Microsoft (ils utilisent peu les signaux sur cette plateforme), et on convient de ne pas permettre de gestion d'exception ou de dynamic_cast dans une fonction signal-safe.

Aaron Ballman fait remarquer que l'écriture proposée empêche d'utiliser memcpy() dans une fonction signal-safe, comme toute fonction n'étant pas explicitement « marquée » du sceau de signal-safe. Patrice Roy suggère que l'on dresse une liste de ces fonctions, mais à court terme un convient d'au moins expliciter que memcpy() et memmove() sont signal-safe car ces deux cas semblent être les plus urgents.

Drafting for class template argument deduction issues

On examine la plus récente version assemblée par Jason Merrill.

Richard Smith signale un petit dérangement grammatical avec la nouvelle écriture et la combinaison des mots template, class et extern. On pense avoir une note quelque part indiquant que la combinaison en question est interdite. On la trouve dans §7.1.7.2 p. 2, alors il faudra ajouter un lien (la section contient une table de cas particuliers acceptables de combinaisons de mots, comme unsigned et long par exemple, pour obtenir un simple-type-specifier).

Jason Merrill fera les retouches.

P0270R2 – Removing C dependencies from signal handler wording

Hubert Tong a fait le tour de ce qui est présumé signal-safe. Il dit avoir des craintes à propos de signal() et de quick_exit(). Dans les deux cas, les fonctions acceptent un handler provenant du code client.. Aaron Ballman mentionne une section du standard du langage C. On demande à l'auteur de la proposition d'ajouter les références aux sections appropriées du standard du langage C.

À propos de « unnecessarily complex wording in p0522r0 »

On parle d'un fil de discussion portant sur des contorsions « peu naturelles » faites par les implémentations pour supporter une pratique de programmation en apparence raisonnable. La question posée par Jason Merrill est de savoir quel sens donner à ce qui suit :

template<class T, class U = T> class B { /* ... */ };
template<template<class> class P, class T> void f(P<T>);
int main() {
  f(B<int>());       // OK?
  f(B<int,float>()); // ill-formed, T deduced to int and float
}
//
// ... puis, pour un autre exemple ...
//
template<typename> struct match;

template<template<typename> class t,typename T>
struct match<t<T> > { typedef int type; }; // #1

template<template<typename,typename> class t,typename T0,typename T1>
struct match<t<T0,T1> > { typedef int type; }; // #2

template<typename,typename = void> struct other { };
typedef match<other<void,void> >::type type;

Il y a aussi le cas de http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4457.html#150 qui remonte à 2006 et qui est instructif. On se demande si les gens qui l'ont implémenté souhaitent revenir en arrière. Richard Smith dit qu'il faut changer les règles, mais sans briser le monde entier. Dans un courriel de 2016 (28 décembre), Richard Smith a soumis une suggestion de solution mais elle n'est pas pleinement testée. On se questionne sur le fait de livrer C++ 17 malgré la possibilité d'un DR sur cette règle, mais il y a des précédents et on pense procéder de cette manière.

On prend la pause pour le dîner vers 11 h 30, et on réfléchira à la proposition de Richard Smith entre-temps.

Je suis allé luncher avec Jonathan Wakely pour prendre connaissance des enjeux de secrétariat d'un comité de standardisation ISO, et pour bavarder parce qu'il est sympathique.

Au retour, je suis allé voir Jeffrey Yasskin pour savoir vers quelle heure je devais me présenter chez LEWG pour la proposition de Vicente J. Botet Escriba , puis j'ai pris quelques instants pour parler avec Lisa Lippincott et prendre le pouls de la proposition de Herb Sutter à propos de <=> (favorable) et des « extras » qu'il avait envisagé (moins clair, mais exploration encouragée).

Retour chez CWG pour 13 h.

Gor Nishanov est parmi nous pour discuter de la TS sur les coroutines. On fait un tour du document. La plupart des retouches sont éditoriales. Richard Smith et Hubert Tong donnent les consignes qui simpliferont la mécanique. C'est pas mal la fin pour les coroutines avec CWG.


Patrice Roy rapporte avoir contacté Billy O'Neal à propos de signal() et du signal-safety sous Windows. Les plans de CWG pour la restriction quant aux blocs try dans cette fonction semblent ne pas poser problème sur cette plateforme.

GB68 – The term 'literal type' is dangerous and misleading

John Spicer propose une formulation. En gros, l'ajout proposé est à l'effet que littéral n'implique pas nécessairement constexpr, bien que ça aide. La terminologie semble convenir, après des retouches mineures pour éviter de possibles lectures inappropriées.

On convient d'en faire un changement éditorial, même s'il s'agissait d'un NB Comment.

Drafting for class template argument deduction issues

Jason Merrill a déplacé une partie du texte d'une section à l'autre, ce qui améliore la cohésion du document dans son ensemble.

Deduction Guides

Mike Spertus nous ramène des détails qui semblent accrocher un peu. Il souhaite valider qu'il s'agit de bogues dans le compilateur de référence ou dans sa bibliothèque plutôt que dans la spécification du mécanisme.

Je dois quitter pour me déplacer vers LEWG. Il est 13 h 15. Mes notes seront moins détaillées que normalement car j'ai dû « animer » un sous-groupe de travail, prendre les notes, éditer le Wiki et présenter à la fois les propositions et nos travaux de réflexion en sous-groupes.

J'arrive chez LEWG pour une présentation par David Sankel sur l'insertion de [[nodiscard]] dans la bibliothèque standard. L'approche proposée est conservatrice : on vise des cas perçus comme évidents, comme std::async(), et il y en a moins qu'on pense (les autres sont std::malloc(), std::launder() et la méthode allocate() des allocateurs). David Stone pense qu'on ne devrait pas l'obliger. Neil MacIntosh dit qu'il l'aimerait bien mais que le fait que le tenir-compte soit optionnel le laisse perplexe. Patrice Roy suggère qu'on ouvre la porte pour une application au choix ds implémenteurs car, dans ce cas, le support optionnel du mécanisme nous dit qu'il n'y a pas de mal à le faire (ce n'est pas aussi risqué qu'ouvrir la porte à constexpr, ou même noexcept).

Il se trouve que dans le document, on trouve d'autres recommandations d'application de [[nodiscard]], ce qui est moins joli. Patrice Roy fait remarquer que le placement new ne doit pas être marqué [[nodiscard]]. Nathan Myers ajoute que les versions surchargées de l'opérateur new sont appelées par le système, pas directement par le code client.

On se sépare ensuite en sous-groupes pour débattre de propositions plus efficacement. Mon groupe comprend moi-même, Lars Bjønnes, Neil MacIntosh, Nathan Myers et Paul Preney.

Nous avons traité des propositions suivantes.

P0319 - Adding Emplace functions for promise<T>/future<T> (de Vicente J. Botet Escriba , présenté par moi)

Patrice Roy présente sommairement l'idée derrière la proposition. Il se dit favorable à ce qui s'y trouve, à ceci près que la qualification noexcept sur les fonctions make_ready_future() ne lui semblent pas à propos. Nous en discutons et convenons qu'il faudrait :

Sur le fond, nous sommes d'avis que c'est une bonne idée.

P0290 - apply() for synchronized_value<T> (d'Anthony Williams)

Patrice Roy dit voir l'intérêt de cette proposition.

Neil MacIntosh souligne que la terminologie ne lui semble pas indiquer dans quel ordre les opérations sont réalisées.

Patrice Roy est d'avis que ça se veut ou outil transactionnel, verrouillant plusieurs objets de manière à ne pas provoquer d'interblocage, puis opérant une même opération (typiquement, une λ) sur l'ensemble de ces objets.

Lars Bjønnes aime beaucoup

Patrice Roy souligne la poésie du type de retour. On parle de la signature :

template <class F, class ... Args>
   decltype(declval<F>(decltype(Args)...)) apply(F && f, Args && ... args);

Patrice Roy fait remarquer qu'il existe un std::apply() pour std::tuple. Neil MacIntosh pense que ça peut être volontaire. Lars Bjønnes dit ne pas voir l'intention explicitée dans la proposition.

Le groupe fait remarquer qu'outre quelques coquilles (des chevrons consommés comme des balises html, par exemple), un questionnement quant au nom apply() qui est peut-être bien choisi mais qu'il faudrait valider, c'est une proposition qui paraît intéressante. Nous suggérons aussi de considérer une éventuelle fonction try_apply() de même signature, mais qui retournerait (par exemple) un optional<...> pour permettre de distinguer le cas où les verrous ont été obtenus de celui où ils ne l'ont pas été.

P0439 - Make std::memory_order a scoped enumeration (de Jonathan Wakely )

Neil MacIntosh dit que ça lui semble tout à fait raisonnable. Nathan Myers aimerait qu'on l'introduise rétroactivement dans C++ 14. Notre lecture est très positive.


Une fois les discussions terminées, j'ai placé nos conclusions sur le Wiki de LEWG, pendant la mini pause, puis nous avons abordé les propositions une à une en grands groupes.

P0518 Allowing copies as arguments to function objects given to parallel algorithms in response to CH11

David Hollman explique le raisonnement derrière la position soutenue par son groupe, et par SG1. La proposition sur la table est de permettre aux algorithmes parallèles de prendre des copies de certains de leurs paramètres, en particulier les opérations. Ce à quoi ils en sont arrivés est de le permettre mais dans le cas des foncteurs utilisés à titre de prédicats seulement.

Après discussion, un vote favorable est tenu.

DRAFT C++ Synchronized Buffered Ostream

Titus Winters présente la proposition. C'est une proposition qui a été traitée à Oulu, mais qui demandait des retouches. Le sous-groupe de travail n'est pas contre la proposition en principe, mais souhaite en voir le syncstreambuf découplé. Ça permettrait des trucs comme :

{
   osyncstream sync{ cout };
   sync << "J'aime " << "mon " << "prof" << endl;
}

Peter Sommerlad parle des enjeux (entre autres, le mutex ne peut être dans le flux, alors il faut une table ou une autre forme de ressource externe quelque par; ça pourrait même être un verrou global). La manière dont est implémentée la synchronisation dépendra de l'implémentation, mais il ne faut pas que, si un individu implémente ses propres flux, ceux-ci consomment un autre verrou pour éviter tout interblocage.

Après discussion, un vote favorable est tenu.

P0261R2 – Distributed Counters

Titus Winters présente la proposition. Le sous-groupe d'étude semble préférer que l'on envoie quelques questions aux auteurs.

Je présente ensuite nos trois dossiers (voir encadré plus haut). On semble accepter nos recommandations. Titus Winters suggère que dans le cas d'Anthony Williams, on demande une comparaison avec des API connexes. Thomas Koëppe signale un breaking change dans les sources pour le travail de Jonathan Wakely , dans le cas où des gens (vilains!) utilisaient les constantes énumérées existantes comme des entiers (faudra ajouter une mention à l'annexe); pour le reste, les nouvelles énumérations de Jonathan Wakely sont votés pour C++ 20.

P0020R4 – Floating Point Atomic

Le sous-groupe de travail est d'avis que c'est prêt pour C++ 20. C'est un sujet délicat, c'est le moins qu'on puisse dire, mais ça semble bien travaillé. Jeffrey Yasskin demande si on devrait insister sur les fournisseurs de matériel (on a des should plutôt que des shall dans certains cas où on ne peut vraiment faire ce qui est demandé sans support matériel). On vote pour savoir si le passage de should à must est nécessaire; ça passe.

Un autre vote pour faire suivre à LWG est pris et passe en vue de C++ 20.

P0019R4 – Floating Point Atomic View

Le sous-groupe de travail est d'avis que c'est une bonne idée. Il y a un risque de comportement indéfini si le constructeur ne rencontre pas certains prérequis. Certains se questionnent sur le nom atomic_view de même que sur le nom atomic_array_view (c'est pas vraiment une vue, en pratique; certains ont parlé d'atomic_ref, d'atomic_wrapper, mais bon). Zach Laine souligne que le constructeur proposé est constexpr, ce qui est peut-être un peu agressif et peut nuire en pratique. On blague sur un atomic_cast<T>, mais Patrice Roy fait remarquer que c'est un nom trop cool et que tout le monde va vouloir s'en servir. On convient de demander le retrait de constexpr sur le constructeur.

Les remarques pour atomic_view<T> et atomic<float> sont du même acabit, mais c'est le même auteur principal.

On termine vers 17 h 5. Jeffrey Yasskin me dit que l'on devrait discuter de std::colony (que je dois présenter) demain après-midi.

En sortant de la rencontre, je suis allé prendre une marche avec Paul Preney, et nous avons croisé Billy Baker, ce qui s'est enchaîné en un souper (nous avons rejoint un groupe d'une dizaine de personnes dont H. Carter Edwards et Olivier Giroux, associés principalement à SG1). J'ai pris une pizza d'un intérêt discutable (poulet barbecue, mais la sauce ressemblait à un produit commercial banal et les légumes étaient inspides) avec une bière locale correcte, suite à quoi je suis revenu parler à mon amoureuse Za.

Je suis tombé d'épuisement vers 20 h.

Jour 3 2 mars 2017

Debout àh, douche, bavardage avec ma belle Za, lectures diverses, réponses à des questions.. Je devrais me lever plus tôt, je n'arrive jamais à tout faite le nécessaire pour préparer ma journée en quatre heures.

Nouvelle triste : un courriel reçu du Collège m'a appris le décès d'une de mes collègues, enseignante en anglais. Je ne connais pas les raisons, mais elle était (il me semble) encore active parmi nous.

J'ai par contre retouché un vieil exemple sur mon site pour utiliser un nouveau mécanisme de C++ 17 dont on a beaucoup parlé cette semaine (les guides de déduction), et j'ai beaucoup apprécié l'expérience. Ça a bien tombé, car j'ai croisé son auteur (Mike Spertus ) en marchant vers la salle de rencontre de CWG ce matin, ce qui m'a permis de lui donner mon appréciation.

Arrivé chez CWG, j'ai pu constater brièvement qu'il y a eu beaucoup de travail accompli en mon absence (mon incursion chez LEWG) hier après-midi.

Gabriel Dos Reis nous revient avec une nouvelle version de son texte sur le Name Lookup avec les modules.

D0583R0 – Modules: Contexts of Template Instantiations and Name Lookup

Gabriel Dos Reis nous indique souhaiter savoir si les mots choisis capturent bien l'intention derrière le design. Il a épluché les règles associées à l'ADL pour valider la démarche, et pense avoir bien capturé l'intention mais souhaite confirmer que la couverture des types « maison » est bien réalisée. Il nous explique son raisonnement (un incident amusant de marqueurs survient; que je vous épargne, mais on a bien ri et il n'y a pas eu de dégâts car Jens Maurer a réagi rapidement). L'exemple que Gabriel Dos Reis met de l'avant (et qui devrait fonctionner) est :

module M;
namespace N {
   struct S {};
}
// z.cpp
import M;
namespace N {
   void f(S);
}
int main() {
   N::S s;
   f(s); // ADL en action
}

Ce cas est le cas « normal », et la terminologie devrait être claire en ce sens. Plusieurs débats chauds s'ensuivent, que je ne reproduirai pas, mais la compréhension que les divers participants ont du modèle proposé ne correspond pas (entre autres, il n'est pas évident que le texte fait fonctionner cet exemple). Ce qui ralentit la progression des modules est en grande partie la difficulté de communiquer les idées.

Après plusieurs minutes d'échange, Jens Maurer rappelle le rôle de CWG, qui n'est pas de questionner l'intention mais de s'assurer que la terminologie inscrite dans le texte du standard soit complète, cohérente et ne mène pas à des implémentations divergentes. Il craint que les règles d'ADL ne soient séparées en deux catégories avec le texte existant, soit une pour les templates et une autre pour le reste. On convient collectivement que le lieu où le fait de parcourir les règles usuelles pour ADL est correct, peu importe comment le passage est écrit. Mike Miller suggère qu'un sous-groupe se réunisse pour clarifier le texte pour les gens de CWG. Richard Smith dit avoir relu les passages et penser que l'intention décrite correspond aux règles écrites : l'instanciation est réalisée au point d'instanciation à partir des informations connues à ce stade, incluant les importations (transitives) des modules importés. La visibilité par voir d'ADL est donc effectivement séparée en deux cas désormais. Mike Miller estime qu'une note doit être ajoutée car même certaines déclarations non-exportées deviennent visibles dans certaines circonstances.

Nathan Sidwell demande une clarification sur le cas de g() ci-dessous :

module M;
namespace N {
   struct S {};
}
// ...
module X;
namespace N {
   export g( ... );
}
// z.cpp
import M;
import X;
namespace N {
   void f(S);
}
int main() {
   N::S s;
   f(s); // ADL en action
}

Sa question est de savoir si g() est dans le namespace partition de N dans le module X, dans le fichier z.cpp, ou dans les deux. Le mot « visible » prend beaucoup d'importance : ce qui est exporté est toujours visible, mais les namespace partitions ne le sont pas toujours.

Autres exemples examinés :

module X;
namespace N {
  void g(...);   // not exported
}
// ...
import M;
import X;
N::S s;
/* export */ g(s);  // not finding N::g
module M;
namespace N {
  inline namespace NI {
    export struct S { };
  }
  void h(S);
}
// ...
module X;
import M;
namespace N {
  /* export */ void g(...); // find only exported g for non-modular ADL
}
export using T = N::S;
// ...
import X;
T s;
g(s);   // finds N::g in X?

Note pour les intéressé(e)s : la terminologie d'un truc comme ceci, où les concepts sont à plusieurs niveaux, et où ils se réfèrent entre eux, demande de travailler la terminologie pour quitter le pluriel et exploiter au maximum le singulier, dans l'optique de pouvoir nommer les éléments et leur référer par ce nom. Une partie du travail fait par Jens Maurer et un peu par Patrice Roy tient à cette reformulation facilitante. En débroussaillant le texte de cette manière, il devient graduellement plus simple à analyser.

Un autre travail de débroussaillage fait par Richard Smith et Gabriel Dos Reis permet de faire ressortir que la visibilité n'est pas transitive. Bjarne Stroustrup recommande de réduire la visibilité à l'essentiel, pour accélérer les temps de compilation.

Jens Maurer suggère que la section sur les points d'instanciation soit adaptée pour tenir compte du nouveau concept d'enchaînement d'instanciations. Gabriel Dos Reis procédera quand le texte migrera d'une TS au IS.

On devrait rediscuter du dossier en début d'après-midi.

Petite pause versh 45. Je vais marcher un peu, et j'en profite pour passer par EWG où, tristement, il n'y a pas de biscuits ce matin. Ça aurait été bon. C'est ce qui manque le plus ici, pour être honnête : des grignotines ou des fruits, pour les pauses, parce que le travail intellectuel un peu intense bénéficie de petits suppléments d'énergie occasionnels.

Contrairement aux derniers jours, il fait un soleil splendide aujourd'hui, mais on ne le voit pas des pièces où nous travaillons (si je n'étais pas allé au petit coin, ce factoïde demeurerait pour moi un mystère).

On reprend vers 10 h 15.

D0270R3: Removing C dependencies from signal handler wording

Le texte de Hans Boehm a été enrichi pour tenir compte des remarques soulevées lors de nos travaux précédents (allocation dynamique de mémoire, gestion d'exceptions, dynamic_cast, etc.). Un enjeu est la présence d'une clause throw dans le code, qui force certaines implémentations à insérer du code de gestion de pile de manière préventive, que le throw soit exécuté ou non). L'idée que nous avions à l'origine était de n'être signal-safe que si le throw était accédé, mais si sa seule présence « dérange l'ordre établi », c'est une autre histoire (l'inlining devient source de préoccupation, par exemple). On investigue et il semble qu'en fin de compte, ce ne soit pas un problème. On examine entre autres ce que fait MSVC et ce que fait clang sur plateforme Microsoft; il y a du code injecté, mais les écritures semblent être atomiques et on ne trouve pas d'allocation dynamique de mémoire), au moins dans le cas où un destructeur non-trivial apparaît dans la fonction.

Évidemment, l'idée de lever une exception dans un signal-handler est un peu démente de toute manière; cela dit, il est vrai que si le fait d'inliner un fonction contenant un throw dans une branche non-prise rend la fonction non-signal-safe, c'est un irritant. Mais on envoie une liste de correctifs mineurs à l'auteur (car on souhaite ce changement pour C++ 17, du fait qu'il améliore de beaucoup la situation actuelle) et au pire, on traitera les détails résiduels dans des DR.

D0250R3: Wording improvements for initialization and thread ids (CWG 2046, 1784)

Un autre texte de Hans Boehm. On parle ici de l'initialisation des objets, globaux ou pas, dans un programme multiprogrammé. Le standard permet l'initialisation parallèle de certains trucs, mais les relations d'ordre existantes ne saisissent pas totalement l'ensemble de ce qui peut être envisagé.

Hubert Tong fait remarquer que le texte actuel ne permet pas de savoir si le programme principal, qui est d'office dans son propre thread, s'exécute  Richard Smith fait remarquer que certains des ajustements demandés par l'auteur de la proposition sont... vagues, ce qui nous rendu frileux sur leur application.

Il y a plusieurs règles nuancées pour déterminer l'ordre d'initialisation des objets. Richard Smith suggère de simplifier par « static initialization strongly occurs before dynamic initialization ». Ça semble raisonnable, mais on va vouloir vérifier auprès de Hans Boehm pour éviter d'échapper un truc subtil. Nathan Sidwell souligne par contre le cas des variables static locales à des fonctions. Les formulations donnant les règles pour initialiser les objets tout en évitant les interblocages sont retravaillées aussi pour éviter toute ambiguïté.

 On examine la question de l'initialisation des variables globales dans une DLL sur Windows. La terminologie utilisée dans la proposition ne semble pas couvrir entièrement les pratiques de cette plateforme.

La proposition exige des compilateurs qu'ils construisent les objets, lorsque le moment choisi leur appartient (p. ex. : les globales), de manière à éviter de créer des interblocages. C'est un problème réputé difficile (c'est le moins qu'on puisse dire), analogue au problème de l'arrêt, et le caractère normatif de l'exigence fait réfléchir. On cherche à clarifier et à encadrer le plus possible cette contrainte. Je remarque au passage que le texte indique que les objets en mémoire locale à un thread ne sont pas détruits si un autre thread appelle std::exit(). C'est un tenir-compte intéressant.

Richard Smith demande ce qui se passe si deux threads exécutent des destructeurs et l'un d'entre eux appelle std::exit(). Patrice Roy se dit d'avis qu'un usager sera en droit de s'attendre à du comportement indéfini d'une horreur pareille. On convient que c'est un cas raisonnable de comportement indéfini. Richard Smith montre que si une implémentation synchronise (par mutex, condition_variable ou autre mécanisme de mise en attente) la destruction des objets d'un thread, et si un appel à std::exit() est fait, un risque d'interblocage en fin de programme survient.

On remarque au passage que le comportement d'appels réentrants à std::exit(), std::atexit() ou std::quick_exit() n'est pas clairement décrit dans le standard de C++. Hubert Tong et Aaron Ballman font remarquer que le standard C place un tel comportement dans la catégorie du comportement indéfini, mais Richard Smith rappelle que c'est un des endroits où C++ ne se base pas sur C. Hubert Tong rappelle que std::atexit() doit nettoyer les variables locales au thread avant l'ensemble des autres variables.

Il y a beaucoup d'ajustements à faire; il n'est pas clair que C++ 17 soit le bon véhicule pour cette proposition dans son état actuel. On verra si nous sommes en mesure de le traiter d'ici demain, mais c'est pas clair.


Avant de quitter pour le dîner, Aaron Ballman indique que 2247. Lambda capture and variable argument list a été traité par LWG et peut être amené pour fins de vote vendredi

La pause du dîner débute vers 11 h 35. Gor Nishanov repasse nous saluer pour discuter modules. Tout le monde a son modèle mental de ce que les règles sont supposées d'être, mais on n'arrive pas à former une correspondance complète avec l'écrit. C'est un cas où la bonne volonté de part et d'autre ne suffit pas, même si tous veulent que ça fonctionne.

Je vais me chercher un sandwich. Il fait très beau, mais beaucoup trop chaud pour mon bien-être personnel (si j'étais en vacances, je serais dans l'eau tout le temps parce que la chaleur ne me convient vraiment, mais vraiment pas). Au retour, je croise Nathan Myers qui me recommande fortement le sorbet aux baies d'acacia qui se vendent non-loin de l'hôtel; j'essaierai de goûter à ça demain matin. J'hésite à dépenser, mon budget étant plutôt limité.

Je me suis aperçu en arrivant dans la salle de LEWG que j'étais appelé à présenter colony, mais aussi contiguous_container et ring_span. Je dois avouer que je ne m'étais pas préparé en conséquence, mais c'est probablement ma faute. Je relis les trois rapidement, et je communique avec Matt Bentley (l'auteur de colony) pour essayer de bien cerner comment vendre son idée chez LEWG.

Comme c'est la coutume, LEWG se sépare en petits groupes, et .le mien discutera de conteneurs et de pointeurs intelligents. Je travaille cet après-midi avec Bryce Adelstein-Lelbach, Hal Finkel, Gor Nishanov, Tim Shen, Jeffrey Yasskin et Mark Zeren.

P0059 Circular-buffer queues

Hal Finkel se dit ravi que quelqu'un cherche à standardiser un nom qui se termine par popper. Patrice Roy se dit d'avis que les auteurs ont fait le travail qui avait été demandé d'eux lors d'itérations antérieures de la proposition (taille fixe, poppers implémentés par politique, pas d'itérateurs, etc.).

Jeffrey Yasskin se dit heureux que le nom ring, qui a une connotation mathématique, ait été abandonné. Il suggère circular_buffer. Bryce Adelstein-Lelbach indique que, si le nom ring_span demeure, il faudrat clarifier sa relation avec les autres types de span qui apparaissent dans le standard. Jeffrey Yasskin dit que le suffixe _span a été choisi car le type n'est pas propriétaire de la mémoire administrée. Bryce Adelstein-Lelbach craint que les usagers ne soient surpris. Mark Zeren souligne que le type ne permet pas d'en extraire des blocs de taille arbitraire. Patrice Roy indique que _buffer serait aussi étrange dû à la non-possession de la mémoire. Jeffrey Yasskin fait remarquer que dans la TS de réseautique, les _buffer ne possèdent pas non plus leur mémoire.

Jeffrey Yasskin dit qu'il souhaiterait que size_type soit un type signé, comme pour les autres span, dans l'optique de réduire les risques d'erreurs. Patrice Roy reprend une suggestion de Hal Finkel qui mettait de l'avant le nom ring_adapter. Hal Finkel indique souhaiter que ce type reste disjoint de tout allocateur.

Bryce Adelstein-Lelbach pense qu'un type connexe, qui reposerait sur un std::vector<T> comme substrat et l'adapterait, serait utile pour l'usager de tous les jours. Il ne bloquerait pas la proposition pour ça, mais souhaite qu'on y réfléchisse. Jeffrey Yasskin rappelle que ce type a d'abord été pensé pour des POD. Patrice Roy rappelle quant à lui que les concepteurs sont des gens du monde du jeu. Patrice Roy indique que le type accepte des T déplaçables si leur affectation par mouvement est noexcept.

Bryce Adelstein-Lelbach remarque qu'il n'est pas clair que le type puisse être construit à partir d'une séquence vide. Il semble que ce soit le cas, mais cela signifie alors que les méthodes front() et back() ont une précondition (!empty()), et dans ce cas, les règles en vigueur chez LEWG et LWG disent que les méthodes ne peuvent être noexcept. Elle doivent au contraire être documentées comme « throws : nothing », comme le souligne Mark Zeren. Hal Finkel demande comment le type signale les cas d'erreurs. Patrice Roy explique que le pseudocode utilise des assertions, mais que sa compréhension est que les auteurs visent plutôt le comportement indéfini. Bryce Adelstein-Lelbach ajoute que les auteurs auront peut-être éventuellement noexcept pour les méthodes front() et back(), mais qu'il leur faudra faire un acte de foi. Hal Finkel fait remarquer qu'il faudrait aussi contraindre les politiques que sont les classes _popper pour y arriver. Il se dit par contre d'avis que ces classes devraient être si simples qu'elles seront inlinées.

Autres remarques :

P0406 Intrusive Containers

Hal Finkel dit avoir pris de Boost::intrusive les conteneurs qui lui semblaient les plus près de ce qui conviendrait pour un conteneur standard. J'ai retiré les particularités qui ne convenaient pas.

Tim Shen demande pourquoi on n'évite pas l'héritage pour ne privilégier l'intrusion par des member hooks. Il dit trouver agaçante une approche reposant sur l'héritage multiple à base de traits. Hal Finkel dit que cela implique utiliser plusieurs pointeurs sur des membres. Jeffrey Yasskin pense que ça vaut la peine d'explorer cette approche alternative. Mark Zeren rappelle qu'avoir recours à de l'héritage impacte la disposition en mémoire des noeuds, ce que l'approche par member hooks évite.

Jeffrey Yasskin fait remarquer la présence d'erreurs typographiques dans le nom de certains types. Bryce Adelstein-Lelbach dit qu'il serait curieux de savoir à quoi nous arriverions avec une approche plus proche des idiomes modernes de C++ (l'implémentation proposée est plus traditionnelle, étant inspirée directement d'une version qui existe depuis quelques années); il suggère d'explorer une approche alternative puis de comparer les résultats. Hal Finkel dit qu'il y aurait lieu d'appliquer l'idiome CRTP.

Bryce Adelstein-Lelbach fait remarquer que l'approche passant par un member hook fonctionne mieux avec auto. Hal Finkel dit qu'il fera un effort pour nettoyer le tout et le rendre plus joli. Jeffrey Yasskin demande si une liste variadique de politiques serait une bonne idée. Hal Finkel dit que c'est possible, mais que ça ne lui a pas semblé nécessaire jusqu'ici.

Hal Finkel demande si, dans le cas des intrusive_unordered_[multi]set et de la gestion de sa mémoire, on devrait privilégier un allocateur ou simplement le laisser administrer un tampon externe. Il nous indique que dans Boost, le tampon est externe et offert par le code client, alors que dans EASTL, les buckets sont fixées sur la base d'un paramètre. Bryce Adelstein-Lelbach préfèrerait éviter les allocateurs s'ils ne sont pas strictement nécessaires. Hal Finkel indique qu'un avantage à administrer un tampon externe est que l'on n'a jamais à faire de rehash. Il ajoute toutefois que le recours à un allocarene serait que pour les buckets, donc que la « performance » demeurerait sous contrôle. Jeffrey Yasskin estime que le design en ce sens dans la proposition telle qu'elle existe présentement est adéquat.

Tim Shen souligne que le type d'allocateur par défaut est std::allocator<T>, alors qu'un std::allocator<T*> lui semble préférable. Patrice Roy recommande std::allocator<T> par souci de cohérence avec les autres conteneurs, quitte à faire un rebind.

Autres remarques :

P0468 An Intrusive Smart Pointer — presented by Isabella Muerte (represented by Bryce)

Bryce Adelstein-Lelbach indique que l'auteur ne savait pas qu'elle pouvait envoyer une mise à jour. La plus récente version de son texte est sur https://github.com/slurps-mad-rips/retain-ptr/blob/master/proposal/p0468.rst

Bryce Adelstein-Lelbach dit que par défaut, cette proposition adopte un objet à la construction et n'incrémente pas le compteur de références. Hal Finkel signale que la motivation affirme des choses sans les appuyer par une justification. Mark Zeren estime que la motivation devrait inclure les gains de « performance » avec une sémantique similaire à cette de shared_ptr. Jeffrey Yasskin pense que le gain est vraiment un gain d'espace. Patrice Roy rappelle l'impact de la Cache, duquel moins gros implique souvent plus rapide.

Tim Shen constate que la proposition prétend implémenter weak_ptr mais ne montre pas comment. Gor Nishanov dit que c'est possible, mais au prix d'allouer un bloc de contrôle supplémentaire. Mark Zeren pense que ce requis n'est pas pertinent.

Mark Zeren est d'avis que le comportement par défaut à la construction devrait être d'incrémenter le compteur de références. Patrice Roy convient que le choix de l'auteure est inabituel. Gor Nishanov est aussi d'avis qu'initialiser le compteur à 1 est la chose à faire. Mark Zeren ajoute qu'il est sage d'offrir une option d'adoption, mais qu'il ne devrait pas s'agir du comportement par défaut. Hal Finkel remarque que cette classe utilise aussi un base hook plutôt qu'un member hook. Tim Shen demande ce qui se produira si quelqu'un hérite de cette classe deux fois ou plus. Mark Zeren constate qu'une approche basée sur des traits pour accéder au compteur de références est probablement plus sage, quitte à l'offrir tout en maintenant un défaut qui reposerait sur l'héritage pour faciliter la tâche ds programmeuses et des programmeurs.

Hal Finkel suggère d'envisager le support de types plus petits pour les cas où il y aura peu de clients. Tim Shen demande si le fait que le type du compteur soit exposé à même le trait poserait problème. Hal Finkel I pense que non, du fait que le type du compteur serait basé sur le type pointé. Gor Nishanov est d'avis que les non-experts pourraient apprécier une approche basée sur des traits aussi.

Jeffrey Yasskin dit que dans Chrome, ils ont à la fois l'approche où l'on initialise le compteur de références à un et celle par adoption, qui laisse le compteur de références à zéro. Il se souvient d'avoir assisté à des débats à ce sujet, mais ne se souvient plus laquelle des deux approches semblait préférable.

Mark Zeren souligne que le document utilise parfois des termes distincts pour une même idée. À son avis, le trait offrirait des opérateurs pour incrémenter ou décrémenter le compteur, et expliquerait comment gérer le cas de nullptr. Gor Nishanov voit que le document soutient qu'une approche reposant sur des traits et utilisant ADL dans Boost est présentée comme supérieure aux alternatives, mais ne voit pas la raison. Bryce Adelstein-Lelbach textera l'auteure. Gor Nishanov suggère une implémentation par défaut (mais remplaçable) pour incrémenter ou décrémenter le compteur. ADL serait utile pour cela.  Tim Shen rappelle qu'on peut spécialiser retain_ptr sur les types maison.

Gor Nishanov confirme que ce type sera utile à même la bibliothèqiue standard, pour implémenter exception_ptr, la TS de réseautique et plusieurs autres trucs. Mark Zeren rappelle que retain_ptr n'a pas à être thread-safe.

Autres remarques :

Brève pause vers 15 h 10. On reprend vers 15 h 25. J'ai passé mon temps à mettre le Wiki à jour

NOTE : À PARTIR D'ICI, TOUT EST PÊLE-MÊLE. JE N'AI PAS EU LE TEMPS DE TOUT ORGANISER PROPREMENT

Je présente nos trois propositions et nbos recommandations ne recontrent pas d'opposition

P0546 Span - foundation for the future — presented by Carter Edwards

P0009 Multidimensional Array View with Polymorphic Layout — presented by Carter Edwards

P0454 A minimal multi-dimensional span, mdspan<> — presented by Carter Edwards

Les trois propositions ont en quelque sorte été traitées en bloc.

Ça semble avoir été bien reçu. Il semble que les paramètres aux templates gagneraient à être enrichis. Le groupe soulève quelques préoccupations, par exemple le sens à donner à un span<int[0]> si on ne peut créer un int[0] sans passer par de l'allocation dynamique de mémoire. Certaines propriétés d'un span présentement semblent être pour des cas nichés, alors on se questionne à savoir si deux types très semblables est préférable à un seul type avec des paramètres presque jamais utilisés pour les dimensions autres que la première.

Pour le volet multidimensionnel, la question est de savoir s'il est préférable d'avoir un nombre variadique de dimensions ou une sorte de span_traits.

Il y a une proposition cousine (p0332 si j'ai bien compris) qui n'a pas été soumise mais qui soutiendrait celle-ci au besoin (des syntaxes comme int[3][][2][]). Elle a été soumise à EWG à la rencontre de Lenexa, mais nous manquions de facteurs motivant son adoption. Les commentaires lors du rejet étaient... divertissants. Jeffrey Yasskin mentionne qu'en attendant, mieux vaut présumer que le changement au niveau du langage ne passera pas, par prudence. Paul Preney suggère d'ajouter un type générique et une série de valeurs, ce qui est moins joli mais fonctionnerait. Carter Edwards dit que P0009 propose ce genre de manoeuvre.

Louis Dionne dit avoir essayé de construire une meilleure signature pour les tableaux multidimensionnels et ses résultats ne sont pas transcendants. La solution simple lui semble être la meilleure. Jeffrey Yasskin mentionne l'existence des template <auto> depuis C++ 17, qui allégeront la syntaxe et éviteront quelques culbutes. Neil MacIntosh demande, si nous obtenons le changement au niveau du langage, pourquoi on utilise encore des tours de magie comme une constante de valeur -1 quelque part. Pablo Halpern donne un indice basé sur la simplification de certaines manoeuvres arithmétiques. Matt Calabrese explique l'intérêt d'avoir un type distinct pour faciliter les spécialisations.

Titus Winters suggère une session conjointe d'EWG et de LEWG pour discuter de la syntaxe de tableaux multidimensionnels. Neil MacIntosh suggère qu'on se concentre sur les propositions qui ne reposent que sur les mécanismes existants entre-temps.

Le span unidimensionnel était a priori une idée de Neil MacIntosh. Cela simplifie le type pour le cas commun, et permet de représenter des séquences non-contiguës de manière compréhensible. Le volet multidimensionnel est nettement plus complexe. Quelqu'un demande si un usager pourrait éviter span s'il était trop complexe; Neil MacIntosh n'est pas certain, mais il mentionne que les usagers de l'une des deux approches tendent à ne pas lire l'API pour l'autre approche, et inversement.

Carter Edwards parle de l'nteraction entre les deux. Si nous faisons deux types, les fonctions à écrire, optimiser et comprendre sont en plus grand nombre. Les traits axés sur la performance accroissent aussi en nombre de manière significative. Des trucs comme l'alignement deviennent des tenir-compte à deux endroits. La capacité d'implémenter restrict est un autre enjeu.

Jeffrey Yasskin demande si les span multidimensionnels servent pour autre chose que des calculs numériques. David Hollman dit que ça sert pour des graphes.

Paul Preney et quelqus autres apportent des approches intermédiaires, inspirées par exemple de la manière par laquelle std::basic_string est construite.

On prend un vote à savoir si une seule proposition unificatrice serait à privilégier. Pas de consensus.

On se demande si un nombre variadique de propriétés est préférable à un seul trait descriptif. On se demande comment il serait possible de combiner un ensemble de traits et les trier de manière à ce que tr<A,B,C> et tr<A,C,B>, par exemple, soient un seul et même type. Louis Dionne dit qu'à son avis, la réponse est non. On ne prend pas de vote, on y va avec des traits.

P0448 A strstream replacement using span<charT> as buffer — presented by Peter Sommerlad

Le sous-groupe a discuté de cette proposition et a plusieurs questions pour l'auteur. Par exemple, quelle est la raison pour laquelle le tampon n'est pas copiable, et ne peut être accédé concurremment, mais la proposition n'explique pas pourquoi. Des explications sur la durée de vie de la std::string utilisée comme substrat seraient appréciées.

L'impression générale du sous-groupe est positive : le design fait mieux que ce qu'il remplace et comble de réels besoins.

P0347 Simplifying simple uses of <random> — presented by Tim Song

Zach Laine souligne les préoccupations du sous-groupe. Par exemple, les intervalles de valeurs possibles peuvent être de divers types. Le recours à un inplace_t reste plus ou moins compris. Le sous-groupe estime que ce mécanisme ne simplifie probablement pas encore assez la mécanique. David Sankel explique où les simplifications apparaissent (c'est surtout dans la génération d'un germe correct).

Titus Winters dit que son équipe chez Google lui a soumis une série de commentaires sur la proposition. Jeffrey Yasskin demande qu'on lui fasse suivre. Les critiques qu'il soulève rejoignent pour l'essentiel ce qui a été mentionné auparavant. Il estime que la clé de cette proposition serait une sorte de fonction de germe standard. Howard E. Hinnant pense que l'initialisation proposée va probablement trop loin. Titus Winters signale que le nombre de bits d'entropie obtenus par une utilisation d'un random_device() est insuffisant pour des applications sérieuses, du moins pour profiter convenablement d'un Mersenne Twister. Howard E. Hinnant pense que ça génère autant de bits qu'il y en a dans un int.

Howard E. Hinnant mentionne l'importance d'avoir un mode qui permet des tests répétables (un germe contrôlé). Quelqu'un pense que Walter E. Brown devrait y jeter un coup d'oeil avant que l'on procède.

Les votes à prendre sont :

Pour le germe, demande-t-on toujours zéro paramètre pour un germe pseudoaléatoire et un paramètre pour un germe fixé? Howard E. Hinnant suggère de faire simplement une fabrique std::make_seeded<moteur>(), ou encore std::seed<moteur>(). Le vote est pris et std::make_seeded<moteur>() semble remporter la faveur

P0466 Layout-compatibility and Pointer-interconvertibility Traits — presented by Lisa Lippincott

Zach Laine explique que lors d'un reinterpret_cast, les conditions requises sont complexes. Ces mécanismes aideraient à faire des choix éclairés. Ces fonctions sont constexpr, mais des traits sont envisageables. David Sankel mentionne que certains ont craint que ceci n'encourage le recours à reinterpret_cast, mais ils ont convenu que ces mécanismes réduisent les risques à l'usage plutôt que de les augmenter. Il y a des cas de nommage (are_common_members, par exemple, ou encore are_layout_compatible, alors que tous les traits du genre sont is_... incluant is_same), mais ça ne semble pas dramatique. Neil MacIntosh pense que is_corresponding_member serait préférable à is_common_member. David Hollman souligne que la cohérence de nommage est particulièrement utile pour les programmeuses et les programmeurs dont l'anglais n'est pas la langue maternelle.

Ça semble avoir été bien reçu. Les changements de noms de mécanismes, de are_ vers is_, sont acceptés. On informe l'auteure qu'elle peut proposer d'autres noms si ceux-ci ne lui conviennent pas. On envoie le tout vers CWG et LWG en vue de C++ 20.

P0045 Function wrapper for const- and ref-qualified operator() — presented by Matt Calabrese

Zach Laine dit que la couverture en sous-groupe n'a pas été complétée. On doit arrêter pour aujourd'hui; il est environ 17 h 5. Le plan est de couvrir cette proposition tôt demain matin.

Bref souper, parler à Za, demander à Clark Nelson à quelle heure débute la session de soirée, erreur sur l'heure, arrivé 15 minutes en retard, debout, intéressant, porte sur la vision, les principes, la procédure et la culture. Pas le genre de truc qui s'écrit (c'est pour régie interne) mais un bon deux heures, et il y aura des suites.

Ma vue de loin baisse...

Jour 4 3 mars 2017

Courte nuit, car je me suis couché un peu plus tard hier soir dû à la séance de soirée. Beaucoup de dossiers à traiter. En particulier, je n'ai pas pu présenter contiguous_container hier, pas plus que colony d'ailleurs, et un échange de courriels avec Jeffrey Yasskin m'a fait réaliser que ces deux dossiers devront être traités samedi après-midi (ce matin, il y a des dossiers chez LEWG qui doivent être traités avant la plénière de l'après-midi), et il se trouve que mon avion, exceptionnellement, quitte tôt en après-midi demain. J'ai donc informé les auteurs de ces deux propositions qu'elles seront traitées, mais que je ne pourrai pas les mousser en personne.

Je retourne donc chez CWG pour les travaux du matin. Auparavant, je fais un « croche » par un petit kiosque de sorbet juste en face de l'hôtel, car j'ai entendu à plusieurs reprises que leur bol de sorbet aux fruits est un délice, mais ils n'ouvrent leurs portes que versh alors ça devra attendre à la pause. On discute encore des dossiers reliés à la plénière d'hier (et c'est tant mieux, soyons honnêtes).

Mike Miller nous informe que certains points contentieux en lien avec les guides de déduction et leur application dans la bibliothèque standard ne seront pas traités ce matin.

Hubert Tong indique qu'il aimerait savoir à quoi s'en tenir avec std::launder() dans la bibliothèque standard. Les exigences du langage et de la bibliothèque ne concordent pas tout à fait. Les règles d'invalidation des itérateurs semblent bien comprises par les usagers, du point de vue de LWG. Jason Merill demande si revenir devant EWG pourrait être fécond. Aaron Ballman demande si une session conjointe serait à propos. Jason Merrill pense qu'un DR pourrait suffire, car le problème remonte à C++ 98. On se questionne sur le véhicule pour Toronto, à savoir une séance de soirée ou une séance conjointe de jour.

(je prends le Wiki vers 8 h 15)

Categorizing Issues by Priority

Issue 636: Dynamic type of objects and aliasing

Issue 900: Lifetime of temporaries in range-based for

std::byte (with Neil MacIntosh -- Neil)

Categorizing Issues by Priority (continued)

Issue 1784: Concurrent execution during static local initialization

Issue 2159: Lambda capture and local thread_local variables

Issue 2189: Surrogate call template

Issue 2222: Additional contexts where instantiation is not required

Issue 2223: Multiple alignas specifiers

2232: thread_local anonymous unions

2240: this is not odr-used in a constant expression

2266: Has dependent type vs is type-dependent

2267: Copy-initialization of temporary in reference direct-initialization

2269: Additional recursive references in aggregate DMIs

2270: Non-inline functions and explicit instantiation declarations

2273: Inheriting constructors vs implicit default constructor

2274: Generic lambda capture vs constexpr if

9:44 break

Pendant la pause, je me suis permis d'aller « voler » des trottoirs aux framboises de la salle d'EWG, puis je suis revenu travailler chez CWG car je suis complètement débordé ce matin.

10:10 end of break

2275: Type-dependence of function template

2278: Copy elision in constant expressions reconsidered

2279: Multiple attribute-specifiers in one attribute-list

2280: Matching a usual deallocation function with placement new

2281: Consistency of aligned operator delete replacement

2282: Consistency with mismatched aligned/non-over-aligned allocation/deallocation functions

2283: Missing complete type requirements

2284: Sequencing of braced-init-list arguments

Je remets le Wiki à Jens Maurer vers 10 h 45.

Core Issue 1299: Temporary objects vs temporary expressions

Jens Maurer explique que nous avons maintenant la matérialisation des temporaires, suggérée par Richard Smith, mais la terminologie manquait pour expliquer quand réaliser cette matérialisation. Le texte proposé couvre cela, puis donne des détails.

Jens Maurer signale que cette liste a été écrite (pour l'essentiel) au moins trois ou quatre fois déjà. On sent le principe DRY se dessiner à l'horizon... éventuellement, du moins.

Clark Nelson nous interrompt, soulignant que certaines propositions soumises pour vote cet après-midi ne semblent pas rattachées à des Core Issues. Mike Miller signale que les Core Issues ont été adressées avant d'être inscrites dans les registres. Jens Maurer signale que l'une d'elles est plutôt que Library Issue, traitée hier soir à 21 h 30. On procédera donc avec elles cet après-midi.

Patrice Roy questionne l'indentation des puces (la deuxième se veut récursive et se termine par « these expressions, » d'une manière à inclure même la première. On discute un peu, mais l'une des puces n'est pas une expression et on cherche une formule plus inclusive, sans trop l'être. On ne trouve pas de solution miracle.

On discute des règles en lien avec l'exemple présenté.

Alisdair Meredith nous interrompt. LWG a besoin d'un nouveau trait, mais celui-ci requiert un peu de Compiler Magic. Ils nous demandent la permission, une chic courtoisie de leur part. Les gens de CWG conviennent qu'il est préférable de générer du Compiler Magic que de calculer couche par-dessus couche de métaprogammation.

On procède avec ceci pour un vote en plénière cet après-midi.

Core Issue 1836: Use of class type being defined in trailing-return-type

L'idée ici est que le type utilisé en tant que type de retour dans une fonction de signature uniforme, ou encore dans une spécification d'exception, peut être incomplet dans la mesure où les membres inconnus ne sont pas utliisés. L'exemple donné est :

struct A {
   char g();
   template<class T> auto f(T t) -> decltype(t + g())
       { return t + g(); }
  };
template auto A::f(int t) -> decltype(t + g());

John Spicer vérifie le texte pour voir jusqu'où l'analyse doit aller. Fedor Sergeev se questionne sur les Data Member Initializers, qui sont dans une Delayed Parse Region. Ça nous fait penser à retirer les spécifications d'exceptions pour la même raison.

On est à l'aise avec le texte une fois celui-ci retravaillé un peu.

Drafting for 2273, 2277: inherited constructor ambiguity

Jason Merrill propose une terminologie. Richard Smith fait remarquer qu'on risque de perdre une partie de l'ordonnancement habituel des règles avec ce qui est proposé. Richard Smith constate aussi que ce texte peut même rendre les règles sur le Name Hiding des constructeurs redondantes.

On interrompt les travaux jusqu'à la plénière de 14 h.

La rencontre de la délégation canadienne s'est tenue de 11 h 45 à 13 h 30 environ. Nous avons discuté des sujets pour lesquels une position canadienne pouvait être requise lors de la plénière cet après-midi (dans certains cas, nous avions consensus, alors que dans d'autres cas nous étions partagés), puis nous avons fait progresser la préparation de la rencontre de Toronto, qui est notre responsabilité collective. Les gens qui habitent à Toronto (ou tout près), ou qui connaissent bien la ville, se chargeront des préparatifs qui demandent une présence (salles, nourriture, alimentation électrique, événements périphériques, transport, logement, etc.) alors que ceux qui habitent moins près (comme moi) auront des tâches auxiliaires. Dans mon cas, si le secrétariat de la rencontre du comité me revient (comme ça semble être le cas pour le moment), j'aurai les mains pleines.

Pour ne pas me faire avoir comme lors de la rencontre de soirée hier soir, je suis arrivé un peu d'avance dans la salle commune (celle d'EWG) pour m'installer et ne préparer. J'ai eu le plaisir de bavarder avec le toujours synpathique Jonathan Caves , que j'apprécie beaucoup, de même qu'avec Walter E. Brown qui m'a parlé de sa jeunesse avec des parents polyglotes (il parle un français surprenant). Jonathan Caves m'a raconté pourquoi les les messages d'erreur de son compilateur ne comprennent pas le mot illegal : certains clients lisaient littéralement against the law.

Clark Nelson nous accueille vers 14 h 10. Comme c'est la coutume, dans le respect du code de conduite d'ISO, je ne personnaliserai pas ce qui suit pour l'essentiel, sauf pour ce qui ne pose pas de problème.

Michael Wong parle de SG5. La préoccupation principale est les pointeurs intelligents dans les blocs transactionnels. Ils ont des téléconférences aux deux semaines.

Lawrence Crowl parle de SG6. Ils ont passé short float à LWG. Ils ont passé les opérations bit à bit à LEWG. Ils ont discuté d'arrondi et de débordement, et cherchent à permettre des modes d'arrondis particuliers sans nécessairement les standardiser. L'écriture d'une TS préliminaire a débuté, et le document sera sur github. Ils espèrent quelque chose de pas si mal pour Toronto.

Chandler Carruth parle de SG7. Ils ont tenu une longue séance de soirée, productive selon lui. Le focus du groupe change et sera renommé en « réflexivité et métaprogrammation » (tiens, l'impact de Louis Dionne!). L'horizon est très positif. Le reste des travaux progresse en sous-groupes. Herb Sutter pense que l'idée est excellente. EWG est impliqué.

SG10 ne s'est pas rencontré.

Gabriel Dos Reis parle de SG12. Ils se sont rencontrés ce matin. Ils ont discuté de std::less, et d'une sorte de constexpr for (je ne suis pas sûr que j'ai bien compris). Certaines manoeuvres d'arithmétique de pointeurs ont aussi été discutées dans ce groupe, et Richard Smith suppléera une proposition. Ville Voutilainen demande si std::launder() a été discuté. Gabriel Dos Reis dit que c'est traité par CWG et LWG

Michael Wong parle de SG14. Les rencontres se font de maniere mensuelle, surtout à distance. Des groupes d'intérêt se forment, incluant un groupe de grande taille sur les systèmes embarqués. Le « chef officieux » est Odin Holmes. Leurs intérêts incluent l'allocation dynamique de mémoire, le temps réel et les exceptions. On a discuté de pointeurs intrusifs, de conteneurs intrusifs, de ring_span, etc. Une de nos propositions est déjà dans C++ 17, et nos efforts se poursuivent.

Hans Boehm parle de SG1. Ils ont nettoyé plusieurs dossiers (algorithmes parallèles, gestion des copies, terminologie, algorithmes numériques, correctifs, initialisation, dépendances envers le langage C, incohérences sur les atomiques, etc.). La question de savoir où s'exécute un .then() pour une future a été discutée. La complexité et les exécuteurs ont été deux autres sujets au menu. Les files concurrentes sont enfin envoyées chez LEWG.

Ville Voutilainen parle d'EWG. Ils ont fini de traiter les NB Comments, ont travaillé sur les guides de discussion, sur les concepts, et ont commencé à travailler sur C++ 20. Ils ont envoyé la réflexivité et les contrants vers LEWG pour d'éventuelles TS. La métaprogrammation et les coroutines ont été discutées. L'opérateur « . » et les références intelligentes seront traités à Toronto. On remercie Andrew Pardoe pour avoir pris des notes toute la semaine.

Jeffrey Yasskin parle de LEWG. Ils ont traiter plusieurs demandes de LWG, plusieurs NAD. Dans leurs gros dossiers, on a les guides de déductions, les NB Comments pour la réseautique et les coroutines. L'opérateur <=> pour la bibliothèque aussi. Plusieurs propositions attendront à Toronto. Demain matin, ils auront une séance conjointe avec EWG. Il remercie les scribes (y a pas de quoi).

Mike Miller parle de CWG. Ils ont tenu trois téléconférences entre les rencontres. La semaine a débuté avec une séance conjointe avec EWG pour les concepts et les guides de déduction. Des efforts importants et fructueux ont été investis sur les modules, qui semblent désormais rejoindre l'assentiment de tous. Deux PDTS seront mis de l'avant aujourd'hui, dont celui-là. Entre autres dossiers, un exemple dans le PDTS mérite un examen de la communauté. La plus récente version des coroutines a été passée en revue et sera mise de l'avant par LWG pour PDTS. Quelques préoccupations résiduelles pour les guides de déduction ont pris du temps cette semaine (on remercie Jason Merrill pour ses efforts). Les Decomposition Declarations sont désormais des Structured Binding Declarations. LWG estime qu'il y a encore des irritants pour std::launder(), et les travaux se poursuivront à Toronto. Pour le moment, pas de changements (quelqu'un dit qu'il y a une défectuosité; Jason Merrill fait remarquer qu'elle remonte à C++ 98, mais qu'on la comprend mieux qu'avant).

Mike Miller indique que certaines des motions mises de l'avant aujourd'hui découlent principalement des travaux lors de téléconférences, mais ont été réexaminées cette semaine en groupe plus complet.

CWG Motions

Motion 1

Move to accept as Defect Reports the issues in P0575R1 (Core Language "ready" issues) and apply their proposed resolutions to the C++ working paper. Consensus.

Motion 2

Move to accept as Defect Reports the issues in P0576R1 (Core Language "tentatively ready" issues) and apply their proposed resolutions to the C++ working paper. Consensus.

Motion 3

Move to accept as Defect Reports the issues in P0622R0 (Additional Core Language Working Group "ready" and "tentatively ready" Issues) and apply their proposed resolutions to the C++ working paper. Consensus.

Motion 4

Move to apply the changes in P0612R0 (NB comment CH2: volatile) to the C++ working paper. Consensus.

Motion 5

Move to accept as a Defect Report the issue in P0613R0 (NB comment GB15: Resolution of Core Issue 2011) and apply its proposed resolution to the C++ working paper. Consensus.

Motion 6

Move to apply the changes in P0298R3 (A byte type definition) to the C++ working paper. Consensus.

Motion 7

Move to apply the changes in P0615R0 (Renaming for structured bindings) to the C++ working paper. Consensus.

Motion 8

Move to apply the changes in P0620R0 (Drafting for class template argument deduction issues) to the C++ working paper. Consensus.

Motion 9

Move to apply the changes in P0270R3 (Removing C dependencies from signal handler wording) to the C++ working paper. Quelqu'un demande des clarifications sur les divergences avec C (il y en a, mais ça a surtout pour effet de clarifier le tout). LWG l'a révisé et est satisfait. Consensus.

Motion 10

Move to apply the changes in P0250R3 (Wording improvements for initilization and thread ids (CWG 2046, 1784)) to the C++ working paper. Quelqu'un demande si main() a encore un thread id avec ce changement, et la réponse est oui. Consensus.

Motion 11

Move to apply the changes in P0582R0 (Modules: Contexts of Template Instantiations and Name Lookup) to the Modules TS working paper, to appoint a review committee composed of Jason Merrill, Nathan Sidwell, and William M. Miller to approve the correctness of the resulting document, and to direct the convener to transmit the approved updated working paper for PDTS ballot. Quelqu'un demande qu'on ne le fasse pas tout de suite, plusieurs demandes de changement n'ayant pas été approuvées; selon cette personne, le document contient des changements de design qui n'ont pas été approuvés par EWG, en particulier la position de la ligne module N; pour indiquer qu'il s'agit du module N. L'éditeur explique pourquoi, selon lui, il n'y a pas de changement au design d'il y a deux ans. Quelqu'un suggère de séparer le vote en deux parties, soit approuver la document d'un côté, et lui accorder le statut de PDTS de l'autre.

Quelqu'un rappelle que la séance de soirée hier nous a conviés à accompagner chaque PDTS d'une série de critères d'acceptation, et demande de connaître les critères ici. Herb Sutter dit que c'était une suggestion qu'on n'a pas adoptée encore, mais que cette proposition est accompagnée d'une forme de supervision avant adoption. Quelqu'un se questionne sur le sens de la motion : est-ce que ça renverse la motion tenue à Issaquah? Est-ce que les changements subséquents seront des DR? Quelqu'un critique le fait que le TS proposé ne comprenne pas les changements demandés. Un plaidoyer vibrant est livré pour encourager les gens à utiliser les modules et à donner un maximum de rétroaction, toute plateforme confondue.

Vote pris, pas de consensus, même si on a fait beaucoup de progrès. On sépare la motion en deux parties :

On prend une pause vers 15 h 30. Il fait très chaud aujourd'hui, et LWG a beaucoup de proposition à mettre de l'avant.

Herb Sutter reprend le plancher vers 15 h 45. Il remercie tous les participants, et particulièrement LWG qui ont eu les mains pleines toute la semaine. On leur doit collectivement beaucoup, et il suggère de leur faire des câlins (consensuels seulement).

Marshall Clow prend le relais. Il remercie tous les participants, en particulier Daniel Krügler qui a tenu le fort à distance et a écrit deux propositions durant la semaine.

LWG motions

Motion 1

Move to appoint an editing committee composed of Geoffrey Romer, Dinka Ranns, Gor Nishanov, and James Dennett to approve the correctness of the Coroutines TS working paper N4649, and to direct the Convener to transmit the approved updated working paper for PDTS ballot. Il y a eu des changements cette semaine, mais ils sont mineurs (surtout pour le respect des nouvelles règles de présentation des documents de standardisation ISO). Herb Sutter souligne que CWG a fait une revue du texte et l'a accepté. Consensus. Gor Nishanov est content.

Motion 2

Move to apply to the C++ working paper the proposed resolutions of all of the issues in P0165R4 (C++ Standard Library Issues to be moved in Kona). Consensus.

Motion 3

Move to apply to the C++ working paper the proposed resolutions of "Review" issues:

2796

tuple should be a literal type

2790

Missing specification of istreambuf_iterator::operator->

2676

Provide filesystem::path overloads for File-based streams

Consensus.

Filesystem (toujours dans LWG, mais il y en a beaucoup)

Motion 4

Move to apply to the C++ working paper the proposed wording in P0317R1 (Directory Entry Caching for Filesystem). Consensus.

Motion 5

Move to apply to the C++ working paper the proposed wording in P0492R2 (Proposed Resolution of C++17 National Body Comments for Filesystems). This resolves NB comments CA 2, CA 3, CA 6, CA 7, US 25, US 31, US 32, US 33, US 34, US 35, US 36, US 37, US 38, US 39, US 40, US 41, US 42, US 43, US 44, US 45, US 46, US 47, US 48, US 49, US 50, US 51, US 52, US 53, US 54, US 55, US 56, US 57, US 58, US 59, US 60, US 61, US 62, US 63, US 73, US 74, US 77, US 78, US 185, FI 14, Late 36, Late 37, Late 42 -- check this list!!! Quelqu'un dit qu'il y en a au moins cinq autres de résolus par celui-ci. Consensus. On félicite Beman Dawes.

Motion 6

Move to apply to the C++ working paper the proposed wording in P0430R2 (File system library on non-POSIX-like operating systems) This resolves NB comments US 75, US 76, US 79, CA 4, CA 5, CA 8. Consensus.

Parallel Algorithms (toujours LWG)

Motion 7

Move to apply to the C++ working paper the proposed wording in P0452R1 (Unifying <numeric> Parallel Algorithms). This resolves NB comments US 161 and US 184. Consensus.

Motion 8

Move to apply to the C++ working paper the proposed wording in P0518R1 (Allowing copies as arguments to function objects given to parallel algorithms in response to CH11) This resolves NB comment CH 11. Consensus.

Motion 9

Move to apply to the C++ working paper the proposed wording in P0523R1 (Wording for CH 10: Complexity of parallel algorithms). This partially resolves NB comment CH 10. Consensus.

Motion 10

Move to apply to the C++ working paper the proposed wording in P0574R1 (Algorithm Complexity Constraints and Parallel Overloads). This also partially resolves NB comment CH 10. Consensus.

Motion 11

Move to apply to the C++ working paper the proposed wording in p0467R2 (Iterator Concerns for Parallel Algorithms). This resolves NB comments US 156 and US 162. Quelqu'un estime que le retrait des InputIterators est une erreur. Un autre souligne qu'il sera plus simple de les intégrer plus tard quand nous aurons de l'expérience et quand nous saurons comment bien les utiliser. L'idée est de le permettre comme une extension conforme, mais d'attendre que nous sachions comment bien le faire avant de le permettre à même le standard. Un implémenteur indique que les supporter mène à du code singulièrement lent. On mentionne que les politiques d'exécution permettront éventuellement d'intégrer les InputIterators, tout en demeurant rapides entre-temps. Quelqu'un se dit d'avis que l'on perd en homogénéité en supprimant une famille d'itérateurs de ce qui est supporté. Quelqu'un mentionne que nous sommes en train de tenir une discussion technique en plénière. Quelqu.un mentionne que l'idée d'un algorithme parallèle est d'être maximalement rapide.

Le vote est tenu. Consensus.

Motion 12

Move to apply to the C++ working paper the proposed wording in P0623R0 (Final C++17 Parallel Algorithms Fixes). This resolves NB comments US 161 and US 184. Consensus.

NB Response Papers (toujours LWG)

Motion 13

Move to apply to the C++ working paper the proposed wording in P0604R0 (Resolving GB 55, US 84, US 85, US 86). We are proposing both options A and B. This resolves NB comments GB 55, US 84, US 85, US 86. Consensus.

Motion 14

Move to apply to the C++ working paper the proposed wording in P0607 (Inline Variables for the Standard Library). We are proposing options A and B2. This resolves NB comments FI 9 and GB 28. Consensus.

Motion 15

Move to apply to the C++ working paper the proposed wording in P0618R0 (Deprecating <codecvt>). This resolves NB comments GB 57, US 64, and CA 9. Quelqu'un fait remarquer qu'il deviendra difficile de compiler sans avertissement avec C++ 17. Un autre indique que les probabilités d'un avertissement sont faibles. Consensus.

Motion 16

Move to revert the application of P0181R1 "Ordered By Default" This resolves FI 18. Marshall Clow nous indique que c'était un ABI Break, et qu'il a fallu reculer sur une décision qui semblait pas si mal au préalable. Consensus.

Motion 17

Move to apply to the C++ working paper the proposed wording in P0156R2 (Variadic Lock guard). This resolves NB comments FI 8, GB 61. C'est juste un changement de nom par rapport à P0156R1 voté plus haut. Consensus.

Motion 18

Move to apply to the C++ working paper the proposed wording in P0599R1 (noexcept for hash functions). This resolves NB comment US 140. Cette contrainte n'affecte que les versions offertes par la bibliothèque standard; les fonctions de hashage du code client ne sont pas assujetties à cette contrainte. Consensus.

Motion 19

Move to apply to the C++ working paper the proposed wording in P0433R2 (Toward a resolution of US7 and US14: Integrating template deduction for class templates into the standard library). This resolves NB comments US 7 and US 14. Un remerciement spécial est offert à Mike Spertus pour son travail colossal dans ce dossier. Consensus.

NB Issue resolutions (toujours LWG)

Motion 20

Move to apply to the C++ working paper the proposed resolutions of all of the issues in P0625R0 (C++ Standard Library Issues Resolved Directly In Kona).

Issue Title NB Comment
2872

Add definition for direct-non-list-initialization

US 107
2890

The definition of 'object state' applies only to class types

US 111
2866

Incorrect derived classes constraints

GB 36
2857

{variant,optional,any}::emplace should return the constructed value

 
2900

The copy and move constructors of optional are not constexpr

US 111
2806

Base class of bad_optional_access

GB 49
2934

optional doesn't compare with T

 
2903

The form of initialization for the emplace-constructors is not specified

US 118
2904

Make variant move-assignment more exception safe

CH 7
2868

Missing specification of bad_any_cast::what()

GB 54
2801

Default-constructibility of unique_ptr

US 122
2905

is_constructible_v<unique_ptr<P,D>, P, D const &> should be false when D is not copy constructible

US 123
2873

Add noexcept to several shared_ptr related functions

US 124
2802

shared_ptr constructor requirements for a deleter

US 127
2874

Constructor shared_ptr::shared_ptr(Y*) should be constrained

US 125
2875

shared_ptr::shared_ptr(Y* | D | […]) constructors should be constrained

US 126
2876

shared_ptr::shared_ptr(const weak_ptr&) constructor should be constrained

US 129
2908

The less-than operator for shared pointers could do more

US 135
2807

std::invoke should use std::is_nothrow_callable

GB 53
2894

The function template std::apply() is required to be constexpr but std::invoke() isn't. Celle-ci dépend d'une particularité entre les mains de CWG et qui n'a pas été traitée, donc elle est exclue du lot

GB 51
2911

An is_aggregate type trait is needed

US 143
2861

basic_string should require that charT match traits::char_type

US 145
2788

basic_string range mutators unintentionally require a default constructible allocator

 
2878

Missing DefaultConstructible requirement for istream_iterator default constructor

US 153
2921

packaged_task and type-erased allocators

US 165

Consensus.

Motion 20b

La suivante est traitée à part de Motion 20 sur demande de l'assemblée.

2911

An is_aggregate type trait is needed

US 143

Quelqu'un demande si ceci a été discuté dans EWG. Quelqu'un indique que des tentatives de discussion ont été tentées dans le passé. Quelqu'un se dit préoccupé du fait que ceci semble ouvrir la porte à une nouvelle technique d'initialisation sélective. Quelqu'un dit avoir parfois besoin de savoir s'il utilise un agrégat. Quelqu'un rappelle que la distinction entre agrégat et non-agrégat est très visible au code client; ceci donne du contrôle au code client pour qui donne dans la programmation générique. Quelqu'un suggère qu'on se débarrasse plutôt de la différence entre agrégats et non-agrégats. LEWG indique avoir tenu un vote favorable, mais avoir exprimé une préoccupation à l'effet que c'est un changement tardif. Quelqu'un dit estimer que ce trait a un impact évolutif. Quelqu'un dit que les implémenteurs de la bibliothèque standard ont une voie de contournement, mais qu'elle est déplaisante.

L'impact évolutif du trait est questionné. Quelqu'un indique que c'est parce que ceci impacte la définition d'un agrégat.

Un vote est tenu. Le consensus est faible, mais il n'y a pas d'opposition de la part d'un NB.

Non NB comment papers (toujours LWG)

Motion 21

Move to apply to the C++ working paper the proposed wording in P0558R1 (Resolving atomic named base class inconsistencies). Consensus

Motion 22

Move to apply to the C++ working paper the proposed wording in P0548R1 (common_type and duration).Ceci corrige un bogue dans un changement récent. Consensus.

Ranges (toujours LWG)

Motion 23

Move to apply to the Ranges TS working paper the proposed wording in P0621 (Ready Ranges TS Issues). Consensus.

WG21 Motions

Motion 1

Move to appoint an editing committee composed of Marshall Clow, Mike Miller, Ville Voutilainen, and Jeffrey Yasskin to approve the correctness of the C++ working paper as modified by the motions approved at this meeting, and to direct the Convener to transmit the approved updated working paper for DIS ballot.

Quelqu'un demande si tous les NB Comments ont été adressés, même si l'une des propositions a été retirée. Herb Sutter indique que cela signifie que dans ce cas, nous aurons « no consensus for change ».

Vote tenu :  Consensus.

Le DIS de C++ 17 est officiel, et les oppositions étaient personnelles (aucun NB ne s'est opposé).

L'étape suivante est une photo de groupe :

C++ 17 est un DIS

C'est chouette d'être là-dessus, quand même.

Je voulais ensuite enfin aller me chercher un sorbet pour voir si c'est aussi bon que ce que les collègues racontent, mais le commerce fermait à 15 h et il était passé 17 h déjà. Je suis donc allé me prendre une bière, féliciter quelques collègues, et dire un petit bonjour à mon amoureuse Za. J'ai travaillé un peu, je suis allé me chercher un riz aux crevettes non-loin, j'ai travaillé encore un peu puis je me suis couché.

Jour 5 4 mars 2017

C'est mon anniversaire et je m'ennuie de ma famille.

Debout versh du matin pour accompagner (virtuellement) mon épouse à son rendez-vous médical. Tristement, nous ne savons pas encore à quoi nous en tenir avec la situation qui nous a causé du stress avant mon départ, puis toute la semaine; nous aurons plus d'information en milieu de la semaine prochaine.

Douche, café, retours de courriels, préparatifs en vue du vol de retour, lectures... Je prends l'avion en début d'après-midi, ce qui me laisse un deux heures pour travailler un peu chez CWG en début de journée.

J'ai vérifié l'heure du Check-Out (11 h, ce qui me permet de laisser mes bagages à ma chambre en attendant, une bonne chose), puis je me suis dirigé vers la salle de CWG mais j'étais un peu trop tôt et la porte était fermée (ce qui n'arrive jamais; faut croire qu'on a franchi une étape hier et que le stress a baissé d'un cran  ) alors je me suis installé chez EWG (qui est un espace à aire ouverte) en attendant. Si vous avez lu ceci au quotidien, vous avez probablement remarqué que j'ai pris du retard jeudi et vendredi dans mon petit journal de voyage, et que mes notes ont toute l'allure d'un chaos confus. Aaron Ballman arrive peu de temps après moi et fait le même constat : c'est la première fois qu'il arrive devant une porte fermée, et il siège sur le comité depuis plus longtemps que moi. Je profite du temps pré-travail pour féliciter quelques collègues à qui je n'ai pas pu serrer la main la veille; certains sont heureux, d'autres auraient aimé que l'on fasse encore plus.

Remarques éparses : je profite de mon dernier matin de sandales (les « Crocs » que ma famille m'a offerts à Noël) pour quelques semaines; je porte autre chose que des bermudas pour la première fois depuis dimanche dernier; et je n'ai qu'un imperméable pour mon retour au Québec (arrivée demain matin) alors que la météo indique une vague de froid.

CWG ouvre ses portes versh 50 avec l'arrivée de Mike Miller et JJens Maurer.

J'ai manqué les premières minutes car je suis (enfin!) parvenu à aller chercher un sorbet, vraiment un smoothie qui se mange à la cuillère. C'est effectivement délicieux!

Paul Preney se joint à nous ce matin, Espérons qu'il s'amuse!

P0388R0 – Permit conversions to arrays of unknown bound

Jens Maurer dit que §8.5.4 p3.8, la terminologie quant à une référence vers un tableau est suspecte.

Jason Merrill se dit nerveux de prime abord, mais une lecture plus approfondie le rassure. Il souligne que §8.5.4 gagnerait à tenir compte d'une temporaire matérialisée.

Patrice Roy pense qu'il manque une puce à §13.3.3.2. On convient que c'est bel et bien le cas.

Hubert Tong fait remarquer que la terminologie existante ne couvre pas correctement la brace elision (qu'en fait, ça l'empêche). Il propose un ajustement capable de capturer cette réalité.

Jens Maurer indique qu'un ajustement général du texte sur la base du standard C++ 17 serait important; les références utilisées datent un peu.

Jason Merrill fait remarquer que §13.3.3.2 p5 mériterait aussi une puce supplémentaire (en fait, que le paragraphe devrait peut-êtrê être une puce), du fait que le tout complète l'énumération qui précède. Il note aussi que les règles ne sont pas nécessairement cohérentes entre elles pour ce qui est de l'ordre dans lequel elles sont traitées.

Thomas Köppe suggère de scinder la proposition en deux, mais le groupe préfère ne pas aller dans cette direction.

Le document est intéressant mais devra être retravaillé.

P0409R1 – Allow lambda capture [ = , this]

Jens Maurer signale son inconfort face au design, mais cela ne nous revient pas.

On ajoute une virgule et on fait de petites retouches.

Sur le plan terminologique, c'est mineur, mais on le regardera à nouveau à Toronto.

P0306R2 – Comma omission and comma deletion

Jens Maurer demande ce que WG14 en pense. Hubert Tong dit qu'ils attendent pour voir ce que WG21 fera. Thomas Köppe l'enverra à WG14 après le vote à Toronto.

Le document a été changé depuis son premier passage chez CWG, mais très peu, et le petit ajout qui y a été fait est avantageux.

Jens Maurer demande s'il existe une implémentation de test. Thomas Köppe dit que non. Semble que toucher au préprocesseur ne soit pas le loisir préféré des gens dans la salle. Jens Maurer demande si les (nombreux) cas de comportement indéfini dans le préprocesseur ont été réglés, mais il semble que non. Le concept de comportement indéfini dans le préprocesseur est ... préoccupant.

D0315R2 Lambdas in unevaluated contexts (Louis Dionne); revision of P0315R1 Lambdas in unevaluated contexts

Hubert Tong liste les changement appliqués au document depuis la dernière révision, incluant la Heisensentence. La partie qui devait être explicitée, selon EWG, était §4 p. 6. L'idée derrière ce passage est un risque accru de violation d'ODR. Patrice Roy demande si les modules règlent le problème. Hubert Tong dit que oui, mais qu'il est possible que l'éditeur de liens ait plus de difficulté à faire son travail que par le passé.

Aaron Ballman fait remarquer que les exemples utilisés mentionnent des noms de fichiers, sujet contentieux, alors que le standard s'exprime en termes d'unités de traduction. Certains ajustements aux pratiques du standard sont faites.

Patrice Roy fait remarquer le recours à une λ non-void sans return, mais c'est légal tant qu'on ne l'appelle pas.

Jens Maurer demande un exemple pour un cas suspect. Hubert Tong explique les règles d'équivalence entre unités de traduction distinctes. Jens Maurer rappelle que sans risque de violation d'ODR, c'est pas nécessaire. Hubert Tong construit un truc comme :

struct X {
   template <class T>
      void f(decltype([]{ return 0; } + T()));
   template <class T>
      void g(char(*)[([]{ return 0;}()+T())]);
};

On blague sur les liens avec Lisp et avec les expression régulières, comme vous vous en doutez probablement.

On travaille fort pour voir ce qui est permis et ce qui ne l'est pas avec ces nouvelles règles. C'est plein de subtilités, de chevrons et de parenthèses. On reverra ceci à Toronto.

Je dois quitter à la pause, faire mon Check-Out et débuter les démarches pour le retour. Mon corps m'envoie des signaux de « c'est assez, va te reposer », mais ça ne sera pas pour tout de suite disons.

Je suis allé collecter mes choses, faire les trucs routiniers pré-voyage (brossage de dents et autres banalités), puis j'ai remis mes clés, préparé la planification du taxi vers l'aéroport, que j'ai gfait venir pour 11 h car mon collègue Louis Dionne a encore un truc à présenter et partagera les frais avec moi (nous prenons le même avion).

La route vers l'aéroport avec Louis Dionne fut agréable; c'est un chic type, très intelligent. Nous sommes tous deux assez fatigués par contre, ce qui se comprend. Arrivés à l'aéroport, nous constatons que nous ne prenons pas le même avion (le sien est même un peu avant le mien, et il a un vol direct vers San Francisco, où il habite et où il travaille maintenant) alors nous nous saluons avant d'aller chacun de son côté.

Comme dans mon souvenir, il y a très peu de prise d'alimentation électrique à l'aéroport de Kona, et l'accès à Internet est payant. Disons que ce n'est pas une force de l'endroit. J'ai trouvé un endroit où la prise de courant fonctionnait, me suis assis par terre (l'aéroport de Kona est totalement à aire ouverte; fait chaud!) et j'ai travaillé en attendant l'avion.


Le vol était inconfortable, mais moins qu'à l'habitude car l'avion n'était pas plein et les sièges derrière le mien (j'étais à côté d'un couple de gens dans la fin de la cinquantaine) étaient tous libres, alors l'agente de bord m'a offert les trois sièges. J'ai donc pu prendre mes aises, du moins un peu. J'ai essayé de dormir pendant le voyage avec des résultats mitigés (un peu se sommeil épars).

À l'aéroport de Los Angeles, j'ai pu trouver un endroit pour charger laptop, téléphone, iPod et autres objets utiles en voyage. Le WiFi était meilleur que lors de mes passages précédents (45 minutes, mais renouvelables si on laisse jouer une publicité dans notre fureteur). J'avais un peu faim, mais les prix à l'aéroport de Los Angeles sont déments (14 USD pour un sandwich au thon banal, sans accompagnement). Je me suis pris un café et un carré granola plutôt santé (le commis a été gentil et m'en a donné deux). J'ai pu travailler un peu avant de prendre mon avion vers Chicago.

Le voyage vers Chicago, lui, était inconfortable. Celles et ceux qui me connaissent le savent : depuis une blessure au coccyx il y a plus de vingt ans déjà (une bête maladresse), je suis très mal quand je suis assis, alors après le voyage de plus de cinq heures de Kona à Los Angeles, celui qui a duré plus de quatre heures de Los Angeles à Chicago n'était pas une partie de plaisir. J'ai encore une fois pu prendre des bribes de sommeil ici et là, par épisodes.

Je suis déjà passé par Chicago, mais quelques minutes à peine et sans changer de terminal. Cette fois, j'ai dû marcher un peu plus (ça a fait du bien!), et j'ai pu constater que c'est un très bel endroit, beaucoup plus propre que les aéroports de New York ou de Los Angeles. Par contre, le WiFi gratuit est valide pour 30 minutes et n'est pas renouvelable, ce qui est ridicule. Oh, et il y a une sévère différence de température entre Kona, Los Angeles et Chicago. On me dit que Montréal est en pleine vague de froid... C'est bête, mais j'ai hâte.

J'ai pris un café et des burritos déjeuner chez McDonald's (j'y tiens pas particulièrement, mais c'était le seul commerce avec des prix raisonnables), travaillé un peu, puis départ vers Montréal, ma femme et mes enfants.


Valid XHTML 1.0 Transitional

CSS Valide !