À propos de WG21, Jacksonville 2018

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 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 quelques années plus tard (C++ 14), et la première mise à jour majeure à laquelle j'ai activement participé, C++ 17, a été votée à la rencontre de Kona 2017.

Nous travaillerons à WG21 pour les prochaines années sur C++ 20, de même que (pour la présente rencontre) sur des correctifs idéalement mineurs à C++ 17. Les objectifs de C++ 20 sont très ambitieux, et font saliver les gens qui, comme moi, cherchent à tirer le maximum de ce que ce langage a à offrir. Certains des éléments les plus importants que nous souhaitions voir intégrés au langage à partie de C++ 17 ont dû être retardés pour diverses raisons, et nous souhaitons les voir faire partie d'un  C++ 20 de grande envergure.

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 :

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). Dans le respect des règles de procédure en vigueur, le nominatif lors des échanges techniques aura été supprimé de la version à laquelle vous aurez accès.

Fin du contenu technique

Au préalable

J'ai manqué la rencontre précédente du comité, à Albuquerque, faute de pouvoir me libérer au Collège. Je suis donc un peu moins à jour qu'à l'habitude dans les affaires courantes du comité. De même, j'ai envoyé cet hiver ma thèse de doctorat en vue de la défendre, et j'ai pris un retard considérable dans la lecture de mes courriels et des propositions dont nous discuterons cette semaine.

Cette semaine, comme à Toronto, je serai secrétaire du comité en l'absence du toujours sympathique Jonathan Wakely.

Jour -1 11 mars 2018

Changement d'heure. Dur sur le corps ce matin. Mes plus jeunes enfants Vayda et Ludo accompagnent et ma belle Za et m'amènent à l'aéroport. J'écris aux étudiants que j'accompagne dans leur rédaction d'essai que je serai difficile à rejoindre pour la semaine qui vient.

Fait chaud à l'aéroport de Philadelphie. Je travaille, dans ma bulle, jusqu'à ce que je m'aperçoive que Dietmar Kühl est assis juste devant moi. On bavarde une trentaine de minutes, puis c'est le temps d'embarquer.

Je ne suis jamais confortable assis trop longtemps, particulièrement en avion. Heureusement, mes deux vols aujourd'hui (Montréal vers Philadelphie, puis Philadelphie vers Jacksonville) sont d'environ deux heures / deux heures trente chacun, ce qui n'est pas dramatique.

Arrivé à l'aéroport, j'ai partagé un taxi avec Dietmar Kühl et Torvald Riegel, et nous avons eu droit à un chauffeur qui avait une vision très ... personnelle, disons, des limites de vitesse et de la sécurité routière. À l'hôtel, évidemment, la densité de membre du comité devient subitement très élevée.

Le check-in se fait sans anicroche. La chambre est propre (au 14e étage), et la télévision est ouverte sur un canal interne qui sert d'économiseur d'écran montrant ce qui peut être fait en ville pour un touriste – donc totalement inutile pour nous, mais c'est une bonne idée. Je voulais aller à l'épicerie chercher du dentifrice (j'en ai, mais je vais en avoir besoin cette semaine) et quelques trucs à grignoter (je cherche toujours à dépenser le moins possible), mais rien n'est possible à distance de marche. On me dit qu'il y a un service de navette gratuit, de jour et la semaine seulement, alors j'essaierai de m'en prévaloir tôt demain matin.

Je suis allé me chercher une bière pour travailler de ma chambre (pas un grand choix, mais quelques trucs corrects). J'en ai profité pour saluer quelques amis, dont Gor Nishanov qui a déjà l'air cuit (il me dit qu'il a dû écrire trois textes en catastrophe cette semaine; avec les coroutine, il travaille vraiment très fort, et on lui devra beaucoup) et Guy Davidson, toujours aussi enthousiaste.

Le reste de la soirée sert à préparer la paperasse pour ma tâche de secrétariat cette semaine... J'ai appris en cours de route que Bjarne Stroustrup, qui vient de gagner quelques prix prestigieux, nous invite pour un souper spécial jeudi soir, auquel j'assisterai avec plaisir.

J'ai réussi à obtenir un mini frigo. Je vais peut-être réussir à atténuer mes frais cette semaine...

Jour 0 12 mars 2018

Debout vers 5 h 30. Comme c'est souvent le cas, le premier puzzle à résoudre fut celui du fonctionnement de la douche (faut pointer vers Cold pour avoir de l'eau chaude... C'est peut-être moi qui suis tout croche, mais il me semble que les hôtels ont souvent des métaphores difficiles à décoder pour la gestion de la température de l'eau).

J'essaie la cafétière (style Keurig) fournie avec la chambre. Le café (rwandais) sent bon. Mon plan d'aller à l'épicerie risque de se réaliser lors de la pause du souper, car ce matin les heures de disponibilité de la navette ne me conviennent pas (je risquerais d'être en retard pour la plénière, et vu que je suis secrétaire, c'est inacceptable).

Je risque de dépanner des absents pour des propositions qui me semblent utiles (mais pas nécessairement prêtes pour adoption), incluant une pour un std::uuid et une pour un std::slot_map. Ça signifie que je risque d'aller faire des tours chez LEWG.


Nous avons droit à du café, des fruits et des viennoiseries (bonne chose; n'ayant pas mangé hier depuis le déjeuner, j'ai un peu faim). Des feuilles nous attendent pour planifier la nourriture à l'hôtel lors des dîners (des buffets, mais je me suis inscrit étant donné que l'hôtel semble un peu loin des sources de nourriture) et lors de l'événement planifié par Bjarne Stroustrup jeudi soir (je m'y suis inscrit aussi).

La semaine qui s'annonce sera chargée : des séances de soirée chaque jour sauf jeudi (dû à l'événement susmentionné) :

 Je prépare ma prise de notes (certains liens et certains documents clés ont été mis à jour depuis hier). Herb Sutter passe me saluer... en français, excellent par ailleurs (il a fait un peu d'immersion par le passé). Je l'entends aussi bavarder en allemand avec Peter Sommerlad. Bravo!

Les travaux débutent à 9 h. Les sessions de soirée sont de 19 h 30 à 22 h. Sur le plan du contenu :

Pour les groupes d'études autres que SG1, qui a sa propre salle à temps complet :

La plénière se termine vers 9 h 50, et les gens se dispersent pour laisser rapidement la salle principale ouverte pour une brève discussion entre un petit groupe d'expert(e)s de CWG et EWG à propos de constraints on non-templates.

CWG débute les travaux à 10 h pour mettre la table avant la pause officielle de 10 h 15.

Mike Miller met la table. Jens Maurer indique quelques propositions à discuter à court terme. On examine la disponibilité des auteurs-clés dans chaque cas pour loger les discussions de chacune dans des cases horaires pertinentes.

Petite discussion avec Thierry Lavoie à propos de ma défense de thèse dans peu de temps (enfin!). Il y a des brownies et du café à notre disposition, une bonne idée.

Les travaux reprennent à 10 h 30. Patrice Roy sera secrétaire en début de parcours, alors que Jens Maurer aide les gens des autres salles dans leur logistique.

Efficient sized delete for variable sized classes – P0722R2

Richard Smith décrit l'idée, soit une variante d'operator delete permettant une destruction par classe. Le premier paramètre ne serait pas un void

Thierry Lavoie remarque une erreur dans un exemple (de c* vers void*). Richard Smith corrige

Thierry Lavoie sur questionne sur le côté formel de "from further consideration" dans p10, mais on semble convenir que ça suffit

Mike Miller demande des précisions sur la relation parent-enfant de §8.5.2.5 p3

Richard Smith : on peut avoir une hiérarchie qui utilise RTTI pour appeler le bon destructeur sans passer par un destructeur virtuel

Mike Miller demande si on vise à couvrir les classes proxy

Richard Smith : le texte existant pourrait suffire. Je vais vérifier.

Jason Merrill : je veux éviter une autre controverse comme operator.()

John Spicer : que veut-on éviter?

Richard Smith : qu'un placement operator delete soit affecté par un destroying operator delete

Jason Merrill : §8.3.5 p12, la forme semble un peu ampoulée (il suggère une tournure plus légère)

Richard Smith : ceci ne couvre pas un cas d'utilisation clé

Mike Miller : devrait-on décrire le rôle de la fonction destroying_delete?

Richard Smith : c'est pas vraiment une fonction, c'est une variable. Ce sera du Library Wording

Andrew Hunter : ceci sera-t-il à coût nul?

Richard Smith : dans certains cas, du moins c'est le but

Mike Miller : le fait qu'il y ait destruction effective pourrait être clarifié dans l'exemple §15.5 p6. Tel quel, la destruction pourrait être ignorée

Richard Smith propose ceci, qui est pas mal :

struct B {
  virtual ~B();
  void operator delete(void*, std::size_t);
};
struct D : B {
  void operator delete(void*);
};
struct E : B {
  void log_deletion();
  void operator delete(E *p, std::destroying_delete_t) {
    p->log_deletion();
    p->~E();
    ::operator delete(p);
  }
};
void f() {
  B* bp = new D;
  delete bp; // 1: uses D::operator delete(void*)
  bp = new E;
  delete bp; // 2: uses E::operator delete(E*, std::destroying_delete_t)
}

Jason Merrill : peut-on avoir un destroying operator delete pour des tableaux?

Richard Smith : pas dans cette version du document, mais c'est une avenue à explorer

Patrice Roy : dans l'exemple, si on a B* f() { return new E; } puis auto p = f(); delete p; alors qu'appellera-t-on?

Richard Smith : le destructeur de B est virtuel. Le destroying operator delete sera appelé

Patrice Roy : le nom me préoccupe, dû aux discussions autour du destructive move

Richard Smith : ça permet à l'objet de prendre le contrôle sur sa propre destruction

Patrice Roy : vendu

Aaron Ballman : risque-t-on d'avoir un jour besoin d'un placement destructing operartor delete? Dis non...

Richard Smith : je ne pense pas

Hubert Tong : je ne pense pas qu'on ait de situation où l'objet est dans un état correct pour être détruit, même avec des objets internes ou des parents...

Richard Smith : peut-être dans le cas du dernier constructeur dans une construction par délégation...

Mike Miller : a-t-on vraiment besoin d'un std::destroying_delete?

Richard Smith : oui, si on appelle operator delete manuellement

Mike Miller : ceci devrait passer en tant que Core Motion samedi

Language support for empty objects -- P0840R1

Une proposition possiblement controversée ici. On définit de nouveaux concepts, dont potentially-overlapping subobject et objects of nonzero size.

Mike Miller questionne la définition proposée, du moins pour certains cas

On a plusieurs discussions, car c'est un sujet extrêmement délicat. Hubert Tong préfère qu'on évite d'aller jouer au niveau des bits, ce qui ouvrirait une boîte de pandore politique

Jason Merrill : la restriction donnée dans §12.2 p.21 sur le common initial sequence devrait-elle dépendre de l'interprétation faite par une implémentation de [[no_unique_address]]?

Richard Smith : je pense que oui

Faisal Vali : ceci a-t-il un impact sur constexpr ou non?

Richard Smith : je ne pense pas

Hubert Tong : je pense qu'il peut y en avoir un

Jason Merrill : en effet, le otherwise neither influence le contexte constexpr

Richard Smith : que fait-on actuellement avec l'adresse des base class subobjects (en particulier face à EBCO)? On devrait probablement avoir le même comportement ici

Jason Merrill se questionne sur la liberté donnée aux implémentations. Richard Smith explique que les objets vides pourraient techniquement être relocalisés au début de leur objet englobant

Aaron Ballman se demande si notre formulation des cas possibles d'objets vides est exhaustive. Richard Smith dit qu'on a des cas actuellement (une classe qui ne contiendrait que des membres de classe, pas de membres d'instances) qui peuvent ne pas être vides selon l'implémentation

Mike Miller : §12.2 p1 pourrait être reformulé (on procède)

Patrice Roy : il y a une restriction pour union U{}; static_assert(!is_empty_v<U>); ... pourquoi?

Hubert Tong et Jason Merrill : c'est un truc sous la gouverne de LWG

Hubert Tong : si j'ai plusieurs instances d'objets de taille zéro dans un struct plus complexe, on semble dire qu'il faut allouer plus d'espace...

Richard Smith : c'est pour couvrir les cas de classes parents, où il y a de la latitude pour les implémentations

Hubert Tong : l'adresse d'un objet vide pourrait-elle être hors de l'objet qui le contient? Faudrait une note...

Jason Merrill : réordonnancer un objet vide me semble impacter le common initial sequence

Mike Miller : seuls les objets non-vides auraient des adresses fixes

Jason Merrill : la position relative des objets dans un standard layout me semble explicitement fixée

Richard Smith : il y a des options de réordonnancement si on change de contrôle d'accès

Jens Maurer : si on place public: devant chaque attribut, ça ouvre la porte à de telles modifications

On ferme pour dîner vers 12 h 6. J'ai suivi un groupe mené par Roger Orr qui allait dans une cour alimentaire d'un petit centre commercial désert non loin de l'hôtel. Service terrible à certains kiosques, mais au mien, ce fut rapide pour moi (poulet pas vilain, jambalaya, légumes un peu trop cuits). J'ai ensuite accompagné Roger Orr et Christof Meerwald pour une marche dans les environs, ce qui fut fort agréable (Roger Orr est un individu d'une gentillesse remarquable).

On recommence avec une courte proposition par Alisdair Meredith, portant sur la suppression d'éléments dépréciés.

Reviewing Deprecated Facilities of C++17 for C++20 – P0619R2

Le changement proposé pour CWG est mineur et se trouve sur le Wiki... de LWG, ce qui cause un peu de confusion, et porte sur la suppression de throw() qui est déprécié depuis un certain temps

Patrice Roy : avec C++ 17, pouvait-on prendre un pointeur de fonction throw() de la même manière qu'un pointeur de fonction noexcept?

Alisdair Meredith : oui. L'un était un remplacement direct pour l'autre

On va de l'avant

Language support for empty objects -- P0840R1

On poursuit les travaux sur ce subtil sujet

Richard Smith a ajouté le passage "The address of a subobject of zero size is that of a byte of storage occupied by the complete object of the subobject" pour clarifier les limites d'une réorganisation des attributs d'instance

Hubert Tong demande si l'adresse peut changer selon les observateurs ou les moments. Patrice Roy blague en parlant d'une Heisenaddress

Richard Smith dit non, d'où le "The" dans "The address..."

Richard Smith précise que les éléments d'un tableau ne sont pas potentially overlapping

Nathan Sidwell fait remarquer un problème terminologique mis en relief par un exemple où on attribut est précédé par trois attributs [[no_unique_address]], or il faut que chaque attribut de taille non-zéro ait une adresse distincte de celle des autres attributs, ce qui brise un peu l'intention

Richard Smith ajoute une petite précision pour clarifier l'idée

Nathan Sidwell fait aussi remarquer que la description du mécanisme insiste sur les possibilités (ou pas) de chevauchements d'objets, alors que le nom du mécanisme parle d'unicité d'adresse, ce qui n'est pas sémantiquement équivalent (pas dramatique, mais à réfléchir)

Faisal Vali fait remarquer que le cas un [[no_unique_address]] appliqué à un int demeure un irritant. Richard Smith ajuste le texte

Jason Merrill revient sur le côté standard layout et common initial sequence et leur caractère conflictuel avec le positionnement en mémoire des objets vides

Richard Smith suggère un type Z contenant un X et un Y dont Y est un struct vide marqué [[no_unique_address]], et où Z dérive de Y. Selon lui, ici, il faut s'assurer que les deux Y soient à des adresses distinctes. Plus clairement :

struct X {};
struct Y {};
struct Z : Y {
   X x;
   [[no_unique_address]] Y y;
};

Hubert Tong questionne le recours à une annotation pour ce mécanisme (c'est une question que j'avais moi-même, mais on en a parlé ce midi et la plupart des gens semblaient accepter qu'il s'agisse d'une position d'EWG donc hors de notre contrôle)

John Spicer : on veut éviter que l'attribut transforme quelque chose de standard layout à non-standard layout. Si tel était son impact, mieux vaut l'ignorer

Hubert Tong : il me semble risqué de permettre un placement new sur un tel objet au cas où ceci provoquerait une zero-initialization (il pense à http://eel.is/c++draft/basic.life en particulier, plus précisément http://eel.is/c++draft/basic.life#8.4 qui demande une extension pour tenir compte des zero-sized subobjects)

Hubert Tong demande comment on peut obtenir ce qu'il nomme le tail padding effect à partir de la terminologie, soit la réutilisation de l'espace résiduel dû au padding résultant de l'alignement des variables. On le fait pour les relations parent-enfant (l'enfant pouvant exploiter implicitement le tail padding du parent), et le texte semble ouvrir la porte à cette optimisation avec les attributs, mais Hubert Tong ne voit pas comment on pourrait y arriver avec le texte actuel

Richard Smith dit avoir essayé de réutiliser la terminologie pour les classes de base, mais n'est pas certain que ce soit suffisamment formel pour être utile

Hubert Tong fait remarquer que nous entrons dans un terrain tout à fait nouveau ici

Richard Smith pense qu'on devrait explorer les ramifications à partir de http://eel.is/c++draft/basic.types#2 dans ce cas

Hubert Tong fait remarquer que plusieurs gens utilisent sizeof pour naviguer les bytes d'un objet, que ce soit bien vu ou non sur la base du texte du standard. Il devient difficile avec ces changements de bien capturer l'étendue des bytes occupés par un objet, considérant le tail padding effect

Richard Smith vérifie, et il se trouve sur l'écriture existante de sizeof couvre bien les nouveaux cas. L'écriture proposée est d'évaluer, pour un type T, sizeof(T) sur la base d'un T qui ne sont pas potentially-overlapping, ce qui évite le cas où sizeof(T)==0

Richard Smith remarque que les bit-fields de taille zéro n'occupent techniquement pas d'espace en mémoire, même s'ils ne sont pas qualifiés [[no_unique_address]], et semblent donc assujettis aux mêmes optimisations et aux mêmes transformations

Faisal Vali se questionne sur l'importance de distinguer les bit-fields des autres sous-objets, mais Richard Smith fait remarquer qu'un bit-field ne possède pas de sous-objets

Jens Maurer suggère qu'on travaille plutôt le texte sur la base d'objets de taille zéro ou non-zéro. Il y a le cas d'un unnamed bit-field of non-zero size qui n'a pas de sous-objets...

Hubert Tong fait remarquer le problème de la compatibilité binaire qui surviendra avec ce mécanisme

On travaille ensuite sur la base de http://eel.is/c++draft/class#7 qui explique les règles d'une classe standard layout pour voir si nous n'avons rien brisé au passage

On procédera avec ceci pour vote en plénière samedi

Core issue 1906 – Name lookup in member friend declaration

On a une divergence très forte d'une implémentation à l'autre sur http://eel.is/c++draft/basic.lookup.unqual#10 ... Sur la base des discussions :

L'enjeu est de reconnaître (ou pas) ce qui suit comme valide, et de lui donner (ou pas) un sens :

namespace A {
  using type = int;
  struct X { void f(int); };
}
namespace B {
  struct Y {
    friend void A::X::f(type);
  };
} 

Notez qu'il y a beaucoup d'autres cas; c'est un peu le chaos. Dans quels espaces nommés et dans quelles classes un compilateur devrait-il fouiller... et dans quel ordre?

Hubert Tong : le texte dans des sections connexes va du comportement le plus spécialisé vers le comportement le moins spécialisé. Peut-on en faire autant ici? Si on s'entend sur le comportement attendu, à tout le moins...

Richard Smith : on a une particularité en ce sens que pour un friend, nous sommes toujours dans une portée englobante

Jens Maurer suggère une approche quant à ce qui devrait être choisi. On échange, on examine des options en espérant trouver ce qui causera le moins de dégâts au code existant

Mike Miller fait remarquer que les gens vont probablement copier / coller les déclarations des fonctions amies; pour cette raison, il faudrait que le choix qui sera fait facilite ce geste

Richard Smith note qu'il faudra faire des ajustements pour les types de retour, à tout le moins

Mike Miller souligne que le point de déclaration d'une fonction amie en tant qu'amie peut toujours pleinement qualifier un nom pour lever l'ambiguïté

Jens Maurer rappelle qu'il y a toujours la syntaxe unifiée de fonctions pour ces cas

Nathan Sidwell note qu'on est en fait en train d'inventer une nouvelle forme de lookup. Faudra probablement consulter EWG

John Spicer pense qu'il serait plus simple de trouver une règle à même CWG pour ce cas un peu niché

Jason Merrill indique que toutes les implémentations sont d'accord sur le premier endroit où fouiller; on peut donc au moins s'entendre là-dessus

La démarche suivie par Clang semble être la plus rassembleuse. On relit http://eel.is/c++draft/basic.lookup.unqual#10 et... on s'entend pour dire NAD en fin de compte, et les implémentations s'ajusteront

Brève pause vers 15 h 30. Je croise Michael Wong,, qui m'a envoyé une invitation pour éditer un document qui (je l'apprends) sera discuté demain. Je vais y travailler tantôt.

Il se trouve que le goûter est fait de biscuits au beurre d'arachides. C'est bon, mais je me renseigne et il y a des participants qui sont allergiques à la présence d'arachides dans la pièce, incluant des gens qui travaillent à CWG. On informe Jens Maurer qu'il serait sage d'avertir les employés de l'hôtel.

On recommence

Allow pack expansion in lambda init-capture – P0780R1

Barry Revzin présente le tout. On parle d'un mécanisme pour capturer des Parameter Packs dans une λ autrement que par copie.

Hubert Tong questionne certains passages terminologiques.

Dinka Ranns : problème de ponctuation dans §8.1.5.2 p17

Barry Revzin : dans §17.6.3 p2, on mentionne que le texte mentionne des cas qui peuvent ne pas fonctionner, mais tous les exemples fonctionnent. Patrice Roy suggère l'ajout d'un cas qui ne fonctionnerait pas. Hubert Tong dit que c'est couvert ailleurs, alors une référence croisée pourrait suffire. John Spicer supprimerait simplement le passage qui mentionne le cas où ça ne fonctionnerait pas, si c'est couvert ailleurs. Hubert Tong n'est pas certain, le contexte étant nouveau

Richard Smith dit que la généralisation de Parameter Pack à Pack tout simplement ne lui semble pas assez clair pour quantifier la taille d'une expansion

Hubert Tong rappelle que les choix terminologiques existants visaient la capacité d'enseigner efficacement le mécanisme

Richard Smith indique qu'on confond la ligne floue entre les templates et leur instanciation

Hubert Tong pense qu'on devra revisiter la manière dont nous parlons des Packs à moyen terme, maintenant qu'ils ne servent plus seulement aux paramètres de fonctions

Jens Maurer propose une avenue qui colle à la formulation amenée par Barry Revzin et qui semble fonctionner à pour le moment

Jason Merrill demande si on devrait écrire [xs = args...]{} ou [xs = args]{} tout simplement

Hubert Tong pense que le ... devrait apparaître avant xs, donc [...xs = args]{}

Patrice Roy fait remarquer que l'écriture args... sied bien à [xs = std::move(args)...]{}

Barry Revzin explique que [xs=args...] tend à donner x0=a,x1=b,x2=c,... etc. ce qui lui semble correspondre au modèle mental des programmeuses et des programmeurs. Richard Smith pense que [...xs=args] est plus raisonnable sur le plan sémantique. Richard Smith pense que c'est dans la talle d'EWG

Patrice Roy demande comment l'appel à std::move() sur args s'exprimerait. Hubert Tong dit que ce serait [...xs=std::move(args)]

Barry Revzin demande s'il doit aller à la rencontre d'EWG pour ceci. Jens Maurer suggère que Richard Smith l'accompagne pour expliquer la cohérence de la démarche proposée

Jason Merrill dit qu'on semble se concentrer sur les unique identifiers, donc sur les id-expressions, mais que le focus lui semble incorrect. Un identifiant n'est pas un objet; ça nomme un objet

Hubert Tong pense que quelque chose est disparu dans la terminologie proposée. Le « named-ness ». On suggère d'autres tournures, comme "if the pack is an init-capture pack, the element is an id-expression designating the variable declared by the init-capture". Jason Merrill pense que le fait qu'ils aient des identifiants ne devrait pas même intervenir ici. On retravaille pour ne parler que du nombre d'éléments de l'expansion. Barry Revzin propose "if the pack is an init-capture pack, the element is an id-expression designating the variable declared by the init-capture that resulted from the instantiation of the pattern where the pack is declared" ce qui est presque (!) de la poésie

Hubert Tong est préoccupé par le mot pattern dans ce cas. On discute un peu. La terminologie des Packs a beaucoup évolué au fil des ans, et le fait qu'ils se répandent un peu partout va demander un travail de fond

Hubert Tong fait remarquer qu'il nous manque des définitions fondamentales pour parler de Packs. Richard Smith constate qu'on en parle partout sans dire clairement ce que c'est, et se demande même si le terme devrait être dans le texte du standard. Les template parameter packs et les function parameter packs sont bien définis; ce sont les Parameter Packs pris isolément qui ne le sont pas. Selon Hubert Tong, tout le discours sur les Packs repose sur sizeof (en fait, sur sizeof...) et sa terminologie

Richard Smith essaie "an init-capture pack results in the capture of the pack expansion of its initializer" qui semble plus près du but. Jason Merrill propose une autre formule, qui rejoint l'assentiment sur le fond : "An init-capture pack introduces an init-capture of each of the elements in the pack expansion of its initializer". On devra en prendre soin un peu pour la qualité de la langue, évidemment

Hubert Tong et Richard Smith proposent ensuite des tournures pour mieux définir la taille d'un Pack en termes de nombre d'éléments, basé sur le nombre d'expansions

Richard Smith propose une clarification du terme Pack qui inclurait les Packs dans le contexte d'une capture, et l'impact de cette normalisation sur sizeof...

Barry Revzin applique les changements. Ça prend un certain temps, mais il fait du bon travail

Mike Miller demande si on va de l'avant avec ceci. Patrice Roy fait remarquer qu'il faut retourner devant EWG auparavant pour la position du ..., ce sur quoi nous sommes toutes et tous d'accord

Hubert Tong constate que nous avons, au passage, corrigé un passage défectueux sur les Fold Expressions... Ouf!

Barry Revzin mentionne http://eel.is/c++draft/expr.prim.fold qui discute de variadiques. On semble penser qu'à cet endroit, c'est acceptable

Jason Merrill suggère une reformulation pour fins de clarification. On arrive à quelque chose de pas mal

Proposed wording for likely and unlikely attributes – P0479R4

Jens Maurer présente pour l'auteur, Clay Trychta, qui est absent

Richard Smith fait remarquer qu'avec cette grammaire, une fonction peut être [[likely]] mais commencer par une instruction throw marquée [[unlikely]]

Patrice Roy relate l'intention des membres de SG14 d'indiquer au compilateur qu'un chemin doit être traité comme s'il était probable... même s'il ne l'est pas, car l'intention est que passer par ce chemin, même si ce n'est qu'occasionnel, soit le comportement en fonction duquel l'optimisation sera faite

Richard Smith suggère un léger ajustement pour éviter des situations absurdes

Richard Smith demande quelle est la conséquence d'appliquer cette annotation sur une étiquette comme un case dans une sélective, particulièrement en conjonction avec [[fallthrough]]. Il suggère que joindre cette étiquette par un saut soit traité différemment de son atteinte par un [[fallthrough]]

David Herring fait remarquer que l'annotation [[likely]] ou [[unlikely]] s'applique à l'étiquette, point

Richard Smith dit qu'un léger ajustement grammatical sera requis

L'auteur sera informé du résultat des discussions, soit le besoin d'un ajustement grammatical pour couvrir correctement les étiquettes et quelques trucs mineurs

On ferme à 17 h 30. Je vais aller souper avec un groupe qui prépare la séance de soirée de mardi soir; c'était pas mon plan initial, mais c'est important. J'espère avoir le temps d'aller à l'épicerie... Mais non, je n'y suis pas arrivé. J'ai donc soupé avec Nicolai Josuttis, Guy Davidson, John McFarlane, Matteuz Pusz et Casey Carter pour préparer la soirée de demain : ce que nous présenterons, dans quel ordre, ce que nous souhaitons tirer des discussions, etc. Je me suis limité à une entrée (excellente par ailleurs, mais 9 USD pour un Caprese tout de même). Une fois la discussion terminée, il restait moins d'une demie heure avant la séance de soirée, et j'en ai profité pour appeler Vayda et Ludo (mais ce dernier dormait déjà), et pour bavarder un peu avec le toujours charmant Walter Brown.

J'étais prêt à prendre des notes pour ce soir, mais Andrew Pardoe est là et semble enthousiaste alors je le laisse aller.

La salle est pleine ce soir, sans surprises.

Constrained declarations terse syntax

Ville Voutilainen demande un vote à main levée pour savoir qui pense que la proposition de Thomas Köppe devrait être acceptée. Il fait de même pour la proposition de Herb Sutter. Pas de grande réaction de part et d'autre. On se lance dans les débats, avec l'humour acide caractéristique de Ville Voutilainen.

Les objectifs sont de progresser sur le plan de la syntaxe... et d'offrir le Chair de belles surprises.

Tom Honermann dit qu'il ne souhaite proposer quelque chose que si la question des résolutions dépendantes ou indépendantes est sujette à débats.

Vittorio Romeo prend le plancher. Ville Voutilainen annonce dix minutes par proposition

Concept-constrained auto P0915R0

Vittorio Romeo dit avoir co-écrit sa proposition avec JL

Vittorio Romeo vise un auto<C> pour déclarer une variable supportant le concept C

Vittorio Romeo : le comportement attendu est un static_assert sur le support du concept C par le type auquel est associé auto<C>. Par exemple, auto<C> obj=f(); ne compilera que si le type retourné par f() supporte C

C'est pas bête, pour être hônnête. L'enjeu est probablement syntaxique ici. L'alternative est d'ajouter static_assert(C<decltype(obj)>) suivant la déclaration, ce qui est plus verbeux

Juan Daniel Garcia aime l'idée mais pas la syntaxe. Il rappelle que la spécification struct devant les struct a été abandonnée il y a longtemps

Ville Voutilainen fait remarquer qu'il y a des chemins explorés par EWG auto<T> aurait un sens particulier

Bjarne Stroustrup pense que c'est un pas en arrière

Chandler Carruth pense que auto tel qu'utilisé motivera les gens à utiliser auto de plus en plus

Gor Nishanov pense aussi qu'on fait un pas en arrière avec ceci. C'est le nom des concepts qui importe selon lui

constexpr bool  dit que la syntaxe lui fait penser à un template template parameter. Ça lui semble... irrégulier

Tom Honermann demande si la proposition couvre les types et les non-types. Vittorio Romeo dit qu'il faut y réfléchir

Vittorio Romeo présente ensuite des extensions possibles à la syntaxe qui mèneraient... à la syntaxe comptacte originale

David Herring dit que la proposition sur la table ne peut pas être vérifiée statiquement pour les non-types

Vittorio Romeo mentionne que la composition logique de concepts serait possible, par auto<C0 && C1> à titre d'exemple

Bjarne Stroustrup critique la syntaxe, l'ayant testée en 2013 et ayant constaté que la lisibilité du code en était réduite

A Case for Simplifying/Improving Natural Syntax Concepts – P0782

Erich Keane et Adam David Allan Martin disent que ce qui semble irriter les gens est la difficulté de comprendre la manière dont les fonctions sont trouvées. Le fait que le concept ConstIndexable proposé en compile que si operator[] est const, mais que si une classe supporte les deux (const et non-const) la version non-const peut être appelée sur un objet non-const (il y a des réactions dans la salle)

Un exemple subséquent montre la difficulté d'intégrer des concepts avec des bibliothèques de différentes provenances. Ils utilisent fire() qui peut avoir deux sens (exécuter une tâche, renvoyer un employé)

Gabriel Dos Reis insiste sur l'importance de rendre la programmation générique plus mainstream, et de réduire la démarcation entre la programmation « concrète » et la programmation générique

La proposition est de changer légèrement les phases de compilation pour réduire les risques d'appeler une fonction... inattendue. Ils argumentent que les temps de compilation ne seront pas impactés

Gabriel Dos Reis dit que ce qu'il veut éviter est l'ajout de mots clés supplémentaires dans la rédaction du code. Il dit encourager la démarchè

Barry Revzin demande ce qu'on devrait faire pour profiter (délibérément) d'ADL. Erich Keane explique quelques options

Chandler Carruth pense que ceci est la première étape vers les concepts de C++ 0x, et les concept maps, qui sont disparus depuis du fait que le problème est extrêmement difficile à résoudre

Gabriel Dos Reis ne pense pas qu'on parle de la même chose; selon lui, ce n'est pas une approche difficile à implémenter

Hal Finkel indique que les surcharges conservées dans la démarche lui semblent conservatrices, et que ça semble gérable

Tom Honermann demande s'il est possible d'appeler une Helper Function qui n'a pas été mentionnée dans les requires clauses étant donné le modèle proposé. Les auteurs ne sont pas d'accord entre eux, c'est amusant. BB pose une question de clarification qui les aide à expliquer leur idée

Bjarne Stroustrup se dit ouvert à une exploration de la complexité de l'idée, pour voir si c'est aussi simple que les auteurs ne le croient ou aussi complexe que ce que Chandler Carruth suppose

Quelqu'un dans la salle dit que l'idée amenée par les auteurs est un Archetype

Lisa Lippincott pense que c'est un problème de surcharge plus qu'un problème d'ADL

An Adjective Syntax for Concepts – P0807R0

Thomas Köppe va dans une direction différente et présente les concepts comme des adjectifs, par exemple template<Sortable class T> ou template<Even int N>

Thomas Köppe explique que sa proposition couvre les types et les non-types, incluant template<auto>

Thomas Köppe : les concepts en tant qu'adjectifs deviennent en fait des contraintes sur des types ou des non-types

Thomas Köppe : le terme auto peut intervenir à divers endroits dans la syntaxe, en tant que type ou en tant que contrainte-toujours-satisfaite

Thomas Köppe apporte plusieurs exemples, incluant des template template variadiques (qu'il marmonne au lieu de nommer, mais on le pardonne étant donné la gymnastique de diction que cela impliquerait)

Ville Voutilainen demande si la proposition couvre les déclarations de variables. Thomas Köppe dit non

Thomas Köppe montre en quoi les concepts-en-tant-qu'adjectifs est un allègement syntaxique sur la syntaxe existante. Il a un exemple avec de multiples concepts pour un même nom, mais n'insiste pas sur celui-ci

Gabriel Dos Reis trouve que c'est merveilleux pour les compilateurs, mais terrible pour l'écriture du code par des programmeuses et des programmeurs. Il revient sur l'objectif d'en arriver à une programmation générique « normale »

Juan Daniel Garcia trouve que cela nous amènerait à utiliser typename de plus en plus, alors que nous avons sur la table des propositions pour supprimer ce mot d'un nombre grandissant de cas

Chandler Carruth pense que cette proposition rend le langage plus lisible, pas moins lisible

Bjarne Stroustrup dit que le volet explicite de la proposition lui semble surtout verbeux, et lui rappelle encore une fois le mot struct que C utilisait beaucoup et que C++ a pour l'essentiel éliminé. Selon lui, alléger la syntaxe envoie le message que le langage est plus simple

Hubert Tong rappelle que auto au lieu d'un concept-en-tant-qu'adjectif menait effectivement à des ambiguïtés

David Herring rappelle les nuances qui motivent les proposition de ce soir

Tom Honermann demande si le mot typename pourrait être supprimé dans le futur, et servir à titre de voie de transition

Tony Van Eerd indique que le changement proposé n'est que syntaxique

Thomas Köppe rappelle que quand on sait ce qu'est un concept, on n'a pas d'ennuis. C'est dans le cas où une ambiguïté demeure que les adjectifs apportent quelque chose

Hubert Tong dit que sans adjectifs, le contexte d'utilisation change la sémantique des déclarations

Concepts in-place syntax – P0745R0

Herb Sutter dit que l'essentiel de la rédaction de cette proposition a été réalisé pendant la rencontre de Toronto

Herb Sutter : l'objectif est de joindre, éventuellement, la syntaxe du Concepts TS. Herb Sutter constate que ce ne sera pas atteint pour C++ 20

Herb Sutter présente sa proposition comme une voie dans cette direction. Il mentionne le recours à <> qui diminue au fil du temps

Herb Sutter se concentre surtout sur les type concepts, pas sur les variable concepts

Herb Sutter présente ses a priori : pouvoir contraindre n'importe quel type déduit, et demeurer cohérent avec le code existant. Il résout f(C a,C b) de manière à ce que les types de a et b puissent être distincts dans la mesure où les deux satisfont C

Herb Sutter : dans les cas où un nom de type n'est pas utilisé, il peut être omis. Par exemple, on peut alors écrire Number{N} res = x*x; ou Number{} res = x*x; au choix (ce qui montre le chemin pour, éventuellement, éliminer {} quand nous aurons une meilleure prise sur les concepts)

Herb Sutter dit préférer passer par les contrats pour contraindre les valeurs, et réserver les concepts pour les types

Une fois un concept nommé, il peut être réutilisé, p. ex. : sort(RandomAccessIterator{It} debut, It fin)

Hubert Tong demande comment l'introduction de non-type template parameter évite des ambiguïtés. Herb Sutter explique que c'est exploré dans la proposition (comment lever l'ambiguïté)

Gabriel Dos Reis pense que les principes ne sont pas rencontrés par certains des exemples de la proposition, en particulier les cas avec {} vides. Il se questionne aussi sur les accolades dans le cas de concepts variadiques

Herb Sutter dit que tout nom entre accolades introduit un nom de type, sans exception

Nicolai Josuttis estime que la syntaxe avec accolades entraîne de la confusion. Herb Sutter dit en discuter dans la proposition, et qu'il existe des alternatives. Nicolai Josuttis pense qu'on a trop d'usages distincts pour les accolades. Louis Dionne pense aussi que les accolades entraînent des irritants

Axel Naumann se questionne sur f(Foo{T}, Bar{T}) qui signifie T satisfait à la fois Foo et Bar, mais lui semble très mélangeant

Vittorio Romeo pense que les accolades vides sont incohérentes, et laisse entendre que {auto} serait une alternative. Herb Sutter dit y avoir pensé mais pense que c'est juste trop

Bjarne Stroustrup dit avoir utilisé les concepts tels que proposés depuis des années, et que les gens s'adaptent très rapidement. Les accolades dans la proposition lui semblent acceptables, mais moins élégantes que la forme compacte d'origine

Tony Van Eerd se dit fortement favorable à cette proposition, dont il apprécie la concision et la cohérence

Bjarne Stroustrup dit que template<Number{T},Number{U}> T square(U) ne permet pas de déduire T sur la base de l'interface (ça fonctionne sur la base de l'implémentation, évidemment). Herb Sutter dit que le nom des types de retour déduits n'est presque jamais utile, le nom n'étant pas réutilisé

Alan Talbot demande pourquoi template<Number{T},Number{U}> T square(U) serait différent de Number{T} square(Number{U}). Herb Sutter dit que c'est un accident de ses diapositives (ils ne sont pas différents), et que la confusion est absente de sa proposition, puis montre un meilleur exemple avec la InputIterator{I} find(I,I,EqualityComparable{value_type<I>})

Des questions surviennent sur l'impact d'écrire auto find(I,I,EqualityComparable{value_type<I>})->InputIterator{I}; Herb Sutter indique que la proposition explique que chacune de ces écritures s'exprime par une réécriture en termes de requires, et que l'écriture est équivalente à la précédente

Jason Merrill réagit à l'introduction d'une toute nouvelle manière de déduire des paramètres de templates. Selon lui, c'est une approche dangereuse

Bryce Lelbach dit préférer ceci à la syntaxe compacte originale, et ne pas tout comprendre des discussions sur la déduction des types ce soir. Il pense que l'écriture proposée est plus claire et plus utilisable que ce qui l'a précédé

Gabriel Dos Reis réagit à template<Mergeable{I0,I1,Out},SortableIterator{Out}> qui mentionne Out deux fois, ce qui lui semble incohérent. Il pense que la proposition est bonne, mais que ce type de cas introduit des règles spéciales et complique le langage

Barry Revzin dit rejoindre Tony Van Eerd et beaucoup aimer cete proposition et sa réécriture systématique en termes de requires.

Gor Nishanov se questionne sur les concepts imbriqués avec la syntaxe proposée. Herb Sutter dit que la syntaxe existante, avec chevrons, demeure supportée. Gor Nishanov demande si les concepts partiels sont supportés, ce qui amènerait des accolades à l'intérieur de chevrons. Herb Sutter dit que oui, et montre une fonction qui retourne vector<Value{V}>

Answers to concept syntax suggestions – P0956R0

Bjarne Stroustrup donne sa perspective sur la syntaxe proposée à l'origine, qu'il favorise et estime à l'avantage des usagers, peu importe les critiques des experts, et sur les alternatives proposées ce soir et par le passé

Bjarne Stroustrup : la syntaxe uniforme proposée à l'origine fonctionne pour les λ et pour les fonctions. Elle est courte, claire et rend la programmatiom générique « normale ». Il se dit d'avis que la plupart des problèmes soulevés en comité sont de faux problèmes

Bjarne Stroustrup dit qu'il pourrait vivre avec ce qu'il nomme le Independent Binding, ou C f(C a,C b) accepte a et b de types distincts mais respectant le concept C

Bjarne Stroustrup se dit d'avis que les usagers n'aiment pas le bruit syntaxique et la redondance. Il suggère de régler les petits irritants et d'aller de l'avant. Il mentionne la suppression de struct au sens de C, et la prochaine réduction des occurrences des mots template et typename dans les sources de C++

Bjarne Stroustrup recommande d'arrêter de se battre avec la syntaxe. Selon lui, la syntaxe existante supporte les cas simples, et nous avons des solutions pour les cas plus complexes

Mike Spertus rejoint Bjarne Stroustrup dans sa position sur l'allègement syntaxique. Il pense aussi qu'une strate entre l'absence totale de contraintes que donne auto et les types pleinement définis qui calcifient la programmation est une bonne chose. Mike Spertus se dit d'avis qu'une syntaxe concise, la traditionnelle ou celle proposée par Herb Sutter, lui semble essentielle

Axel Naumann dit que les concepts sont importants dans des programmes écrits par des non-experts. Pour lui, l'enjeu est de voir comment ces individus perçoivent les concepts, et dans son expérience, ils n'ont pas de problème. Axel Naumann se dit ouvert aux proposition de Bjarne Stroustrup et de Herb Sutter

Chandler Carruth ne pense pas que les concepts sont pour les expert(e)s non plus. Chandler Carruth dit toutefois que dans bien des cas, les gens écrivent des templates pour fins de spécialisation, mais pas nécessairement pour fins de programmation générique. Selon Chandler Carruth, c'est au coeur de la question : les templates ne sont pas des fonctions normales, et c'est pourquoi il préfèrerait les garder distincts du code normal

Bjarne Stroustrup pense que Chandler Carruth applique une perspective plus étroite de la programmation générique que lui, et ce pour des raisons historiques. Selon Bjarne Stroustrup, l'objectif est de réduire les différences entre la programmation générique et la programmation normale

Robert Douglas dit avoir utilisé les concepts pour des cours en-ligne, et n'avoir pas constaté de différence dans la qualité du code livré avec ou sans la syntaxe concise traditionnelle

Herb Sutter rappelle souhaiter la syntaxe concise, et se dit heureux qu'il y ait maintenant de l'ouverture pour les Independent Bindings. Herb Sutter dit que si sa proposition de syntaxe était acceptée, considérant cette ouverture, il serait ouvert à rendre les accolades optionnelles dans les cas où elles pourraient être vides et considérer le reste comme une extension à la syntaxe traditionnelle

Tony Van Eerd mentionne une présentation du langage Swift, où le code générique évite le mot template... et c'est un punchline!

Bryce Lelbach rappelle le vote contre une syntaxe concise à Toronto, et ne pense pas que nous ayons fait du progrès sur bien des irritants depuis

Patrice Roy rappelle que le vote à Toronto fut en fait « pour », mais sans consensus

Gabriel Dos Reis suggère un vote pour la seule question du Independent Binding

Bjarne Stroustrup rappelle l'arrivé hâtive de la spécialisation des templates sur la base des types, qu'il jugeait particulièrement importante dès le début

Herb Sutter dit que selon lui, il y a deux irritants à la syntaxe concise : la question du Independent Binding, et la présence ou pas du mot template pour clarifier la présentation (Herb Sutter dit que cette évidence syntaxique était ce qu'il avait en tête avec les accolades). Il pense que peu importe le choix fait, cette addition visuelle apaiserait les craintes

John Spicer se dit en général d'accord avec Herb Sutter sur le principe d'un marqueur, même léger, distinguant le code générique du code traditionnel, tout en permettant un allègement syntaxique important en comparaison avec ce que nous avons aujourd'hui. John Spicer accepte les divergences d'opinion sur la capacité ou pas de distinguer le code générique du code qui ne l'est pas

Tom Honermann rappelle les questionnements soulevés à Toronto et suggère de les garder en tête lors de votes

Hubert Tong dit que les noms de concepts peuvent, aujourd'hui, être des valeurs ou des types, surtout si on accepte la syntaxe concise. Ceci suggère à son avis un retour du Most Vexing Parse

David Herring fait un plaidoyer pour l'Independent Binding, et rejoint Hubert Tong dans ses préoccupations

Zach Laine fait un plaidoyer pour la possibilité d'utiliser une syntaxe plus verbeuse dans les cas où clarifier le code est important. Selon lui, l'important est d'avoir des options

Bjarne Stroustrup dit que l'important selon lui est que les syntaxes soient équivalentes. Il plaide pour que l'on profite des années d'expérience (plus de quinze!) accumulées à ce sujet


Ville Voutilainen annonce la tenue des votes. En fin de compte, la poursuite des travaux de P0782R0 est encouragée, et il en va de même pour la poursuite des travaux de P0745R0. Les autres options reçoivent un accueil plus tiède. Le souhait de distinguer les templates du code traditionnel semble demeurer. Herb Sutter dit souhaiter que son approche porte fruit.

Ouf. Grosse soirée qui devait se terminer à 22 h mais a dépassé le seuil de 22 h 30. Je reviens à ma chambre travailler un peu, puis dodo...

Jour 1 13 mars 2018

Réveil à 5 h, mais debout vers 5 h 30 (fatigué). Douche, café, constat que je suis noyé dans les courriels.

Préparation en vue de la séance de soirée, sur la base des travaux d'Allan Deustch (son slot_map, que je présenterai, sur la base de sa propre présentation à https://www.youtube.com/watch?v=SHaAR7XPtNU&authuser=0) et d'une matrice comparative des forces et faiblesses des divers conteneurs, à la fois ceux déjà standardisé et ceux proposés pour fins de standardisation (Nicolai Josuttis a une approche intéressante pour visualiser les niches occupées par chacun).

J'ai aussi eu une discussion en ligne avec le dynamique et brillant Odin Holmes sur une collaboration pour une éventuelle proposition visant un sujet délicat qui touche les gens qui oeuvrent dans les systèmes embarqués ou à basse latence.

Alors que les gens s'installent chez CWG, nous discutons de la soirée d'hier, et de ses conséquences. L'impression qui s'en dégage est ce que je qualifierais d'optimisme prudent

Jens Maurer et Faisal Vali nous ont acheté des bananes. Mioum!

Mike Miller explique que nous voudrons probablement participer, tous ou en partie, aux discussions sur les coroutine et leur intégration dans l'IS de C++ 20 chez EWG plus tard aujourd'hui. C'est un sujet contentieux, encore aujourd'hui, surtout sur le plan de l'interface proposée, Nous convenons que CWG ne se réunira qu'après ces discussions, pour assurer le quorum

Jens Maurer nous apprend que SG12 se rencontre... ce matin. Je ne suis pas le seul à être pris par surprise. Hubert Tong y va tout de suite; ça m'embête un peu, car j'aurais aimé y être mais pour ce matin, ça ne me convient pas

On fait le plan de match de la journée

Hubert Tong revient; il semble que SG12 ne peut se rencontrer ce matin finalement

Static reflection – P01945R5

Jens Maurer donne un aperçu du travail à faire dans ce document

Axel Naumann ajoute qu'il serait sage que CWG passe en revue une partie du texte de LWG du fait que les deux se recoupent en partie

Jens Maurer fait remarquer que reflexpr retourne un type incomplet, ce qui est une nouveauté. C'est un fait une bonne idée : ça soustrait ces méta-objets à investigation par voie de traits (des trucs comme is_abstract_v<T> ne sont pas définis dans un tel cas). Axel Naumann note qu'il devra repasser devant EWG pour cela, car ça change le design

Faisal Vali pense que :: est applicable sur un type incomplet, mais Jason Merrill indique que ce n'est possible qu'au moment du design du type. Jason Merrill clarifie : ces méta-objets ne sont en fait pas tant des types que des handles pour décrire des types

Jens Maurer note que tester si un type T est complet est la seule propriété de T qui varie en pratique selon le point auquel reflexpr(T) sera appliqué

Richard Smith pense que s'assurer que rien d'autre ne change selon le point de réflexivité est essentiel ici, pour éviter une explosion de la complexité

Jens Maurer indique que la liste de points à considérer est fixée dans le texte par des puces, donc chaque changement sera observé et validé

Nathan Sidwell explore la question d'une classe interne avec déclaration a priori, mais utilisée dans une méthode. Le type est-il complet au point d'utilisation?

Jens Maurer distingue la complétion dans la classe et la complétion hors de la classe (comme dans un pImpl). Un exemple :

struct E {
  struct M;
};
using T = reflexpr(E);
struct E::M { };
// T reflects incomplete E::M? Later consensus: no

Richard Smith fait remarquer que reflexpr(T) pour un T générique permet de détecter si T a été instancié. La capacité d'instancier un type variera avec les spécialisations, par-dessus le marché

Jason Merrill pense qu'appliquer reflexpr(T) pour un T générique force l'instanciation de T, tout simplement

Richard Smith suggère que la formulation soit ajustée pour exiger que T soit défini au point où reflexpr(T) sera appliqué, pour que le programme soit bien formé. Ça évite de garder la trace de l'état potentiellement incomplet de T selon les points d'utilisation de reflexpr(T)

Jens Maurer : il faut que ce soit un immediate context

Richard Smith : que fait-on dans le cas où on passe de tableau de dimension connue à tableau de dimension inconnue?

Richard Smith : peut-on faire de la réflexivité sur les paramètres par défaut?

Jens Maurer : on ne peut faire de réflexivité sur les fonctions ou sur les templates

Axel Naumann : on peut toutefois faire de la réflexivité sur les template parameters

Richard Smith fait remarquer à Axel Naumann qu'il est possible d'obtenir un type de tableau à travers le mécanisme décrit par le document. Ceci semble surprendre

Richard Smith demande quel est le linkage du type retourné par reflexpr

Axel Naumann pense que tout usage de reflexpr devrait être local à l'unité de traduction

Faisal Vali soulève la question d'une fonction comme auto f() { return reflexpr(int); }

Richard Smith demande ce qui se produira si deux instanciations d'un même template impliquant un reflexpr en tant que type

Patrice Roy demande si ce cas ressemble à celui des λ en contextes non-évalués

Faisal Vali dit que ces types n'ont pas de linkage

Jens Maurer propose cet exemple :

struct C;
template<class T>
   void f(reflexpr(C), T);
template<class T>
   void f(reflexpr(C), T);   // redeclaration?

Richard Smith dit avoir un autre cas en tête, soit celui d'un reflexpr par un friend. Jens Maurer est surpris, pensant que reflexpr se limitait aux membres publics, mais en fait reflexpr s'applique aux membres accessibles :

struct S;
struct C {
private:
  template<class T>
  void f(reflexpr(S), T);
};
struct S {
  template<class T>
  friend void C::f(reflexpr(S), T);   // redeclaration? Access rules for C are may be different
};

John Spicer et Richard Smith discutent de l'impact de reflexpr sur les ABI. Il se trouve qu'il y a bel et bien des similitudes avec le cas des λ dans des contextes semblables

Hubert Tong fait remarquer que, si chaque appel à reflexpr donne un type distinct, le problème des types incomplets disparaît en quelque sorte

On discute. L'approche générant des types distincts à chaque appel semble très coûteuse, malgré ses avantages. Hubert Tong trace un parallèle avec deux objets distincts ayant la même valeur. John Spicer penche pour unspecified, question de laisser de la latitude aux implémentations

Il semble se dessiner des cas de comportement indéfini à la compilation (brrr). Roger Orr recommande que l'expérimentation par voie de TS mène à un suivi serré des questions ouvertes

Patrice Roy demande comment cette génération de métatypes distincts à chaque application de reflexpr rejoint reflects_same<reflexpr(T), reflexpr(T)>. Axel Naumann dit que c'est précisément la raison d'être de reflects_same, qui diffère du trait std::is_same. Jens Maurer indique qu'il est possible d'atteindre le type sur lequel la réflexivité s'applique et d'utiliser std::is_same sur ce type aussi

Nathan Sidwell soulève un autre exemple amusant :

struct X { };
using T1 = reflexpr(X);
using T2 = reflexpr(X);
constexpr bool b = std::is_same_v<T1, T2>;   // unspecified value ... brrr

Jens Maurer rappelle l'importance de la nomenclature reflects the same, qui ne signifie pas is the same

Pour reflects the same, Richard Smith aimerait une précision pour savoir si c'est une question de nommage ou d'entité. Il mentionne le cas de la réflexivité sur un alias de type. Il signale le cas (légal, mais tellement vilain) de typedef X X; (pensez à typedef struct X { } X; comme on le voit en C... Sur lequel des deux X la réflexivité s'appliquerait-elle?)

Richard Smith mentionne le cas particulier d'un alias sur un type obtenu par voie de reflexpr, par exemple reflexpr(M) deux fois sur un alias M donné. La question semble ouverte :

struct C { };
using C1 = reflexpr(C);
using C2 = reflexpr(C);
// reflects_same<C1,C2> is false (not represented in the wording)

Ouf, de grosses questions pour un gros mécanisme...

Brève pause à 10 h 15. Je cherche Gabriel Dos Reis pour essayer de faire en sorte de placer la rencontre de SG12 après la rencontre conjointe EWG et CWG sur les coroutine. Il semble trouver qu'il s'agit d'une bonne idée.

On attaque la question des contrats

Support for contract based programming in C++ – P0542R3

Juan Daniel Garcia explique brièvement les travaux qui ont mené à cette version du document, et fait un rappel de ce que font les contrats tels que proposés. La syntaxe choisie chemine sur la base de celle utilisée pour les annotations

Mike Miller demande si la portion qui dépend de LWG a été couverte déjà par ce groupe. Juan Daniel Garcia dit que oui

Mike Miller demande si Juan Daniel Garcia estime que cette proposition devrait être amenée par LWG ou par CWG à la fin de la semaine. Juan Daniel Garcia pense que ça relève de CWG

Aaron Ballman parle du côté potentiellement évalué d'un contrat. Gabriel Dos Reis explique que bien que la syntaxe suive celle des annotations, les contrats ne peuvent être ignorés par le compilateur. Aaron Ballman dit que cette subilité le préoccupe; entre autres, WG14 semble selon lui enclin à supporter les annotations, mais seulement si elles n'ont pas d'impact sémantique, et il craint que l'on se dirige vers un conflit. Gabriel Dos Reis dit que la question a été débattue plusieurs fois avec EWG

La forme grammaticale choisie est :

contract-attribute-specifier:
   [[ expects contract-levelopt  : conditional-expression ]]
   [[ ensures contract-levelopt  identifieropt : conditional-expression ]]
   [[ assert contract-levelopt  : conditional-expression ]]

contract-level:
   always
   default
   audit
   axiom

Dinka Ranns souligne une formule qui peut être interprétée de manière ambiguë. John Lakos propose une formule qui ressemble à une forme légale, avec introduction d'un terme pour utilisation ultérieure

Thierry Lavoie remarque des règles qui indiquent que les expressions ne peuvent avoir d'effets de bord, mais que la grammaire ne le prévient pas. Jens Maurer estime que la syntaxe n'est pas le bon véhicule pour de telles restrictions

Mike Miller se questionne sur le terme local entity qui lui semble redondant

John Spicer fait remarquer que tel qu'exprimé, la restriction sur les effets de bord à une local entity ne convient pas, car cela ouvre la porte à la modification d'objets globaux ou à des entrées / sorties

Gabriel Dos Reis demande si side-effect-free serait une avenue préférable

John Lakos a eu plusieurs discussions sur le concept de side-effect, et que tout a un side-effect en pratique, même l'ajout d'une instruction en langage d'assembleur

Thierry Lavoie insiste sur la relation avec la syntaxe des annotations, qui devrait être ignorable

John Lakos est d'accord. Cela dit, selon lui, l'idée est de s'assurer que toute évaluation n'ait d'effets pratiques qu'à l'intérieur de cette évaluation, rien d'observable à l'extérieur

Jens Maurer souligne que observable behavior est défini dans le Core Wording, et que la terminologie est importante pour discuter formellement d'effets de bord

John Lakos revient sur les effets de bord : il importe que l'état du programme ne soit pas différent, de manière observable, après évaluation des conditions d'un contrat. Il accepterait les affichages pour fins de débogage par exemple

Mike Miller pense que ça devrait donner dans le comportement indéfini

John Lakos pense qu'un programme devrait s'exécuter de la même manière avec ou sans évaluation de contrats

Jens Maurer revient sur ce qui peut être interdit lexicalement et syntaxiquement dans un contrat : en fait-on quelque chose qui donne dans le comportement indéfini ou quelque chose qui soit mal formé?

John Lakos pense que si un programme se comporte différemment avec et sans contrat, il devrait donner dans le comportement indéfini, mais qu'on devrait espérer que les compilateurs nous laissent déboguer en affichant des trucs

Hubert Tong se questionne sur notre capacité d'exprimer ceci formellement

Aaron Ballman : si un contrat utilise assert() ce qui mène à std::abort(), est-ce un problème?

John Lakos : std::abort() est clairement un effet de bord

Mike Miller : il faut élargir §10.6.11 p8 pour couvrir les objets non-locaux

Ben Saks pense qu'on pourrait s'inspirer du texte sur constexpr pour restreindre les effets de bord

Roger Orr rappelle que dans un programme multiprogrammé, chaque accès à une variable peut changer le comportement global de manière imprévisible

Aaron Ballman parle de la différence entre utiliser std::endl et utiliser std::printf()... Peut-on présumer que le code dépend de l'occurrence ou pas d'un objet global comme le tampon de sortie?

Mike Miller rappelle le groupe à l'ordre, car nous entrons en territoire d'EWG

John Spicer est surtout préoccupé par le sens de "shall have no observable effect" dans le texte. Quelles sont les restrictions attendues?

Hubert Tong rappelle que même lire d'un flux impacte l'exécution du programme sur la base du texte écrit. Une lecture invalide a un impact, une lecture valide a un impact différent

John Lakos conteste cette assertion pour un programme monoprogrammé, mais Aaron Ballman mentionne la lecture d'une variable volatile, ce qui semble clarifier l'idée

Mike Miller demande si la définition formelle de observable behavior convient au sens véhiculé dans le texte. Gabriel Dos Reis recommande de consulter Ville Voutilainen

John Lakos travaille sur la base d'une définition large du terme observable effect, et ça ressemble à la définition formelle sans s'y conformer

John Lakos demande si l'interaction avec un débogueur externe compte pour effet observable. Le consensus est clairement non

Gabriel Dos Reis dit que l'évaluation d'un contrat est en quelque sorte isolée des autres évaluations du programme. Un comportement indéfini dans un contrat ne devrait pas impacter le reste du programme

John Lakos n'est pas d'accord, et pense que les contrats devraient vivre au même niveau que le reste du programme

Jens Maurer paraphrase : [for contracts] there is no interior. John Lakos insiste : pas de conditions particulière. Gabriel Dos Reis demande si les optimiseurs peuvent utiliser un comportement indéfini dans un contrat pour changer le comportement du programme. John Lakos dit non. On est donc d'accord, et il reste du travail à faire dans le document pour décrire cette intention

Nathan Sidwell fait remarquer que l'interaction entre noexcept et une violation de contrat laisse perplexe sur lequel d'entre l'appel à std::terminate() et l'appel à la fonction de signature void(std::contract_violation&) surviendra en pratique. Jens Maurer dit que, sur le plan notionnel, les contrats sont évalués d'abord, même si c'est un mensonge pour assurer le bonheur de certains individus

John Lakos présente les contrats comme une forme de programmation défensive, pour détecter les formellement programmeurs idiots avant que d'autres programmeurs ne puissent le constater. On se bidonne un peu

Mike Miller souligne une contradiction sur les effets d'une violation de noexcept dans le texte proposé

Patrice Roy rappelle l'importance de laisser ce comportement implementation-defined tel qu'il l'est présentement. Nathan Sidwell dit que le stack unwinding obligatoire serait utile pour les contrats, dans une optique de débogage

Jens Maurer souligne que dans le texte actuel, un function-try-block pourrait interférer avec les contrats si une exception est levée dans une évaluation de contrat

Dinka Ranns demande une clarification sur un passage qui discute d'accès public ou non

Mike Miller demande si les contrats sont des clients de la fonction ou s'ils sont contraints aux membres publics

Hubert Tong dit que la contrainte est sur public, pas sur les droits d'accès

Jason Merrill se dit étonné. Juan Daniel Garcia dit ne pas l'avoir compris ainsi

John Lakos dit que le contrat doit se baser strictement sur l'interface publique de ce qui est soumis au contrat

Dinka Ranns dit que §10.6.11.1 p5 devrait alors être retravaillé pour éviter le contournement d'intention par voie de friend

Aaron Ballman aborde la question des continuation modes dans les notes non-normatives. Il préférerait une approche normative

Roger Orr dit que §10.6.11 p9, qui discute de contract levels, bénéficierait aussi d'une approche normative

Gabriel Dos Reis fait remarquer le passage The translation of a program consisting of translation units where the build level is not the same in all translation units is conditionally supported. There shall be no programmatic way of setting, modifying or querying the build level of a translation unit. Jens Maurer fait remarquer qu'il y a d'énormes conséquences à une telle approche, et estime qu'il faut clarifier ce qui est possible dans une compilation avec de multiples modalités. Mike Miller dit ill-formed, no diagnostic required. Hubert Tong confirme

Il y a un risque de violation d'ODR. Hubert Tong suggère qu'on la rende implementation-defined. John Lakos indique que c'est un problème au moment du build, pas à même les sources. Hubert Tong dit que l'ajustement proposé aura l'effet attendu; il ajoute que nous pouvons exiger d'une implémentation qu'elle indique qu'elle supporte (ou pas) le mécanisme

Hubert Tong constate d'autres irritant avec les qualifications d'accès, la clause pour friend n'étant pas suffisante pour véhiculer l'intention. On vérifie le point de vérification (au point d'appel ou au point de définition? C'est le point de définition qui est souhaité), et on confirme que dans ce cas, il faut travailler un peu le texte pour obtenir l'effet souhaité

Hubert Tong explique : il y a des mécanismes, dans une hiérarchie de classes, de restreindre l'accès à des membres, et il y en a beaucoup. Selon lui, il peut être avantageux de déplacer la perspective pour atteindre l'objectif. John Lakos rappelle l'intention, Roger Orr clarifie avec des détails, et Hubert Tong prépare un exemple

On stoppe vers midi. Je demande à Faisal Vali le chemin vers l'épicerie où il a trouvé les bananes, chemin qu'il me montre (pas terriblement compliqué, mais avec quelques périls, la ville n'étant pas exactement conviviale pour les piétons). Truc amusant : je vérifie les directions avec les gens du lobby, qui sont surpris que je sois disposé à marcher... quinze minutes!

Le chemin se passe bien, outre le fait que les feux pour piétons ne sont pas tous fonctionnels, comme moi et d'autres piétonnes et piétons l'avont découvert. L'épicerie comprend des légumes et des fruits frais, un bon choix de fromages, mais un petit choix de bière (ça reste tout de même beaucoup moins cher qu'à l'hôtel).

Une fois à la caisse, je croise Dinka Ranns et Marshall Clow qui ont, comme moi, pris une marche pour se chercher quelque chose de pas trop cher à grignoter. Nous marchons ensemble vers l'hôtel par un autre chemin, beaucoup plus agréable et à peine plus long, qui longe la rivière. J'ai le temps de placer mes quelques achats (sandwich, crudités, fromage, bière) au frigo, de manger une bouchée rapidement, puis je me dirige vers la salle où EWG et CWG convergeront.

Sans surprises, la salle est pleine à craquer

Ville Voutilainen nous accueille, et remarque que CWG est présent en totalité. Il se demande pourquoi. On rit un peu

Merge Coroutines TS into C++20 working draft – P0912R0

Gor Nishanov présente ce document comme un bref plaidoyer pour poser ce geste qu'il considère urgent, soit intégrer au IS de C++ 20 les coroutine telles que décrites dans la TS

Coroutines TS Use Cases and Design Issues – D0973R0

Geoffrey Rohmer prend le plancher. Il dit que le besoin de coroutine est criant pour son entrerprise, et qu'il en va de même pour des mécanismes de signalement d'erreurs qui soient distincts des exceptions. Il plaide pour le recours à expected<T,E> et montre à quel point cela allègerait le code

Bjarne Stroustrup demande pourquoi ne pas utiliser des exceptions. Geoffrey Rohmer dit avoir plusieurs raisons, plusieurs sans intérêt pour la communauté. Geoffrey Rohmer mentionne aussi les résultats d'un sondage récent indiquant que la plupart des programmeuses et des programmeurs aiment avoir une alternative aux exceptions. Bjarne Stroustrup indique que l'exemple proposé se prête précisément aux exceptions. Geoffrey Rohmer dit en pas contrôler le Style Guide de Google

Louis Dionne dit qu'Amazon utilise des exceptions, mais pas partout, et qu'il y a de la place pour des alternatives. Geoffrey Rohmer insiste sur le fait qu'il n'argumente pas contre les exceptions avec cette proposition

Geoffrey Rohmer dit que son problème avec les coroutine est qu'elles allouent dynamiquement des ressources pour faciliter le transfert de contrôle entre fils d'exécution. Geoffrey Rohmer dit que son entreprise souhaite migrer une quantité importante de code vers les coroutine, et que cette allocation systématique est un frein

Geoffrey Rohmer pense qu'éviter l'allocation dynamique systématique est une optimisation difficile à automatiser à même le compilateur. Ville Voutilainen dit que la solution n'est pas évidente à ses yeux. Geoffrey Rohmer dit que son groupe compte apporter une proposition en ce sens à Rapperswil. Ville Voutilainen demande un aperçu. Geoffrey Rohmer dit que c'est un correctif sémantique. Chandler Carruth donne un aperçu où le choix d'allouer un pas repose sur les types

Geoffrey Rohmer se dit d'avis que les coroutine risquent d'être perçues comme inefficaces si l'allocation dynamique est systématique. Il estime qu'une alternative, bien documentée, aidera à l'adoption du mécanisme

Geoffrey Rohmer montre ensuite des risques réels avec le recours à des paramètres const & dans des contextes susceptibles d'être suspendus; il trace un parallèle direct avec la capture par référence dans une λ. Selon lui, il est possible d'améliorer la syntaxe de la TS pour réduire ce risque

Geoffrey Rohmer fait ensuite un plaidoyer pour le remplacement de co_return par ... return, ce qui était le souhait original de Gor Nishanov (qui rit silencieusement juste à côté de moi). Daveed Vandevoorde rappelle que les raisons pour co_return sont sérieuses, et que la proposition semble les rejeter du revers de la main. Gor Nishanov clarifie le propos : future<int> f() { co_return 5; } compilera car co_return sait comment faire une future<int> à partir d'un int, donc il y a une différence; Geoffrey Rohmer suggère que la conversion soit faite au point d'appel. Gor Nishanov donne des détails pour les bénéfices de co_return. Geoffrey Rohmer pense que permettre return faciliterait la migration du code existant

Geoffrey Rohmer estime que la TS comprend une quinzaine de points de personnalisation, sans compter operator new. Il est d'avis que ce degré de personnalisation nous coûte cher en termes de convivialité. Il se dit d'avis que les points de personnalisation peuvent être remplacés par du code client. Gabriel Dos Reis voit cela comme un argument pour offrir des points de personnalisation... avec des comportements par défaut pour le commun des mortels. David Herring dit que ce qui est Boilerplate devrait faire partie de la bibliothèque standard. Gor Nishanov précise ce que les gens tendent à personnaliser, en pratique

Geoffrey Rohmer argumente que co_await met en valeur que le code existant favorise le cas asynchrone, qui n'est pas le seul pertinent selon lui. Geoffrey Rohmer critique aussi la composabilité de co_await imbriqués. Ville Voutilainen demande ce que Geoffrey Rohmer privilégie; Geoffrey Rohmer pense que de la ponctuation serait préférable à un mot clé ici. Il avance que unwrap pourrait aussi être intéressant (Gor Nishanov suggère co_unwrap, et on se bidonne). Chandler Carruth dit que selon lui, l'inversion de contrôle souhaitée dans la gestion d'erreurs est la même que celle souhaitée dans le code asynchrone. Chandler Carruth dit enseigner les coroutine en les présentant comme des automates; Geoffrey Rohmer dit qu'il les présenterait en termes d'unwrapping (on évite le terme monade avec soin; ça blague dans la salle). Geoffrey Rohmer pense que l'on ne peut pas supporter la monade « liste » avec les coroutine telles que proposées

Geoffrey Rohmer dit que l'allocation systématique empêche les coroutine constexpr. Louis Dionne fait valoir que ce problème est peut-être déjà réglé avec l'avènement de possibles allocations dynamiques constexpr. Geoffrey Rohmer en prend note

Gor Nishanov demande des précisions sur ce qui nuit, avec allocation, à expected<T,E>. Geoffrey Rohmer répond que l'ajout d'un coût est inacceptable

A Response to "D0973r0: Coroutines TS Use Cases and Design Issues" – D0978R0

Gor Nishanov remercie Geoffrey Rohmer pour sa contribution, puis explique les cas d'utilisations envisagés pour les coroutine, tout en rappelant que le mécanisme est ouvert. Ce sont les bibliothèques qui leur donnent forme et sens

Gor Nishanov dit ne pas avoir été contacté pour fins de guidance dans la conception d'une application de coroutine pour expected<T,E>. Geoffrey Rohmer dit avoir lunché avec Geoffrey Rohmer à Albuquerque. Gor Nishanov offre des excuses

Gor Nishanov indique la difficulté de bannir les paramètres par référence. Geoffrey Rohmer dit ne pas souhaiter aller là, mais espère offrir un meilleur soutien aux usagers pour éviter une partie des possibles accidents associés à cette pratique. Vittorio Romeo parle de la difficulté de bannir certains types comme string_view. Ville Voutilainen dit que les usagers pervers contourneront toute protection que nous pourrions envisager

Eric Niebler signale un problème avec la terminologie, qui laisse entendre que les références copieraient les référés. Gor Nishanov suggère un bug report

Gor Nishanov se montre ouvert au retour de return au lieu de co_return (je souris), et de revenir à yield au lieu de co_yield. Il explique les enjeux. Entre autres, il faut qu'il y ait assez de consensus pour la déduction des types de retour pour que les λ en bénéficient aussi

Geoffrey Rohmer pense que coroutine est le bon terme pour définir la réification d'un calcul sous forme d'un objet

Pour ce qui est de constexpr, Gor Nishanov comprend l'intérêt de réaliser une initialisation statique d'un tableau par coroutine, dans le cas où le compilateur reconnaît l'absence de risques de suspension d'une fonction. Geoffrey Rohmer trace une distinction entre non-resuming coroutine (son cas d'utilisation) et non-suspending coroutine (ce dont Gor Nishanov parle). Geoffrey Rohmer suggère un trait std::is_non_suspending<class> qui dériverait de true_type pour expected<T,E>

Gor Nishanov réagit ensuite au cas des points de personnalisation, expliquant avoir optimisé en termes des besoins des auteurs de bibliothèques. Selon lui, c'est une tâche qui n'affecte que quelques personnes, tous des spécialistes. Les coroutine handles sont typiquement implémentées par des intrinsèques et sont, techniquement, des void*

Geoffrey Rohmer fait remarquer que le passage par un void* provoque un effacement de type et craint les coûts. Gor Nishanov dit qu'un mot (deux, en fait : convertible to) a été changé dans le Core Wording pour faciliter la génération de code efficace

Gor Nishanov arrive enfin au coeur du débat, soit l'allocation élidable des allocations, et aborde le point de design de fond derrière les fonctions résumables. Il explique que le compilateur génère ce code et, en pratique, peut souvent l'élider (la démonstration a été faite par Clang) du moins quand l'exécution de la coroutine est délimitée par la portée de son appelant

Enfin, Gor Nishanov reprend point par point les critiques de la proposition de Geoffrey Rohmer, et montre, code à l'appui. Gor Nishanov donne tout un show et a droit à des applaudissements. Il montre pourquoi la séparation d'une coroutine en composants personnalisables facilite l'optimisation du code, et parfois même l'élision de l'allocation dynamique de mémoire

Richard Smith trouve un problème potentiel avec l'un des exemples, du moins dans le cas où le compilateur ne parviendrait pas à réaliser de l'inlining. Gor Nishanov explique pourquoi le problème n'existe pas selon lui (la réflexion se base sur la coroutine handle qui ne peut sortir du contexte appelant). Richard Smith et Gor Nishanov font du ping pong et conviennent d'aller en parler ultérieurement

Chandler Carruth fait une distinction entre le code compilé avec ou sans optimisations, et signale une différence importante entre les deux versions

Richard Smith ne pense pas que le heap elision possible avec les coroutine puisse un jour être aussi fiable que RVO ou NRVO. Il explique pourquoi

Herb Sutter rappelle la distinction entre le Zero-Overhead Principle et l'absence de coûts. Il sépare le principe en deux parties : (a) you don't pay for what you don't use, et (b) si vous écriviez le tout manuellement, vous ne feriez pas mieux

Gor Nishanov montre un exemple simple (une page recto) par lequel il est possible d'entreposer les états d'une coroutine où bon nous semble. Un peu de ping pong s'ensuit entre Gor Nishanov et Geoffrey Rohmer sur des détails d'implémentation (Gor Nishanov passe par un operator new spécialisé); Gor Nishanov propose ce lien godbolt à titre de démonstration

Enfin, Gor Nishanov propose un correctif simple et implicite pour le support implicite et sans allocation de expected<T,E> pour les coroutine non-résumables, mais se dit d'avis que le special-casing pour expected<T,E> est un sujet qui dépasse le cas spécifique des coroutine

Chandler Carruth et Gor Nishanov débattent d'options pour améliorer le contrôle des usagers sans impacter négativement la lisibilité

Eric Niebler favorise le maintien d'une API de base simple et utilisable et d'une API plus complexe pour les experts. Il parle de std::string, d'un point de vue utilisation, puis d'un point de vue implémentation

Herb Sutter dit que tous aimeraient une implémentation à coût nul de tous les mécanismes, et se demande à quel point nous sommes près ou loin de cet idéal (il sait que c'est fichtrement rapide sur toutes les plateformes déjà). Il se demande aussi s'il est possible de faire mieux manuellement, et s'il reste un ε il aimerait savoir lequel

Gor Nishanov dit que si l'on observe le code généré pour un automate, on constatera une allocation dynamique des tables sous-jacentes

Roger Orr dit discuter avec Christopher Kohlhoff, qui se dit préoccupé par l'absence de terminologie encadrant (ou pas) les cas menant à une allocation dynamique de ressources

Gor Nishanov rappelle le temps qu'il nous a fallu pour garantir, par la terminologie, Copy Elision

Roger Orr pense que c'est pour cela qu'une TS serait le bon véhicule pour les coroutine. Gor Nishanov dit qu'avec ce discours, on ne livrerait jamais de mise à jour du standard

Herb Sutter reprend l'exemple de std::string soulevé par Eric Niebler, mais insiste sur std::vector, dont l'implémentation a été raffinée après livraison

Bjarne Stroustrup dit que nous avons une TS qui fait un travail remarquable pour ce en fonction de quoi elle a été conçue; les nouveaux cas d'utilisation ne sont pas aussi bien couverts par la TS, mais ce n'est pas une surprise

On prend une pause vers 15 h 30 sans avoir épuisé le sujet. Les autres groupes impliqués (dont CWG et SG12) consultent Ville Voutilainen pour savoir de combien de temps il pense avoir besoin pour résoudre la situation; il dit pouvoir s'en tirer en moins d'une demie-heure après la pause.

Je profite du moment pour serrer la main de Vittorio Romeo, chic et brave type, dont c'est la première expérience ici. Il se dit fatigué mais heureux d'être ici. J'échange aussi quelques mots avec le toujours sympathique Andrew Pardoe.

Herb Sutter fait un rappel quant à l'importance de choix de mots qui soient Gender-Neutral. Bravo!

Gabriel Dos Reis demande s'il est possible d'écrire du code de coroutine à la fois simples à utiliser, et sans la moindre allocation dynamique de mémoire

Ville Voutilainen pense qu'il est possible d'avoir des coroutine types qui évitent l'allocation dynamique de mémoire. Chandler Carruth dit que sont équipe et lui explorent des avenues en ce sens

Torvald Riegel pense que la TS mériterait plus de temps

Herb Sutter dit qu'on a eu cette discussion il y a deux ans. Nous n'avons pas reçu de meilleure proposition depuis, et le design des coroutine n'a pas changé de manière fondamentale depuis

Alisdair Meredith dit que les gens qui ont utilisé ce que propose la TS nous donnent justement une rétroaction aujourd'hui. Selon lui, nous devrions les écouter, sinon à quoi bon passer par ce processus expérimental

Herb Sutter revient sur le fait qu'il y a eu des échanges justement ici, à Jacksonville en 2016, ouvrant la porte à une expérimentation pour une alternative aux coroutine telles que proposées, et avoir indiqué que le temps comptait. Il y a désaccord entre Herb Sutter et Torvald Riegel sur les détails mais pas sur le principe

Ville Voutilainen rappelle que la partie terminologique des coroutine doit être prête dans trois mois. Le temps file

John Spicer rappelle sa compréhension du processus des TS pour obtenir une rétroaction du public sur les mécanismes explorés. Il pense aussi qu'ayant reçu une rétroaction de qualité, il serait hâtif de procéder à une intégration dans l'IS sans offrir à cette rétroaction l'attention qu'elle mérite

Chandler Carruth comprend que l'expérimentation prenne du temps, mais que l'intégration accélérée n'est pas avantageuse considérant que la rétroaction attendue nous est bel et bien livrée

Geoffrey Rohmer pense que les problèmes de fond qu'il a soulevés ne sont pas pleinement couverts par ce qui a été présenté

Herb Sutter dit qu'une proposition alternative devrait être drôlement solide considérant les coroutine existantes, dont la terminologie a été ficelée et qui ont été implémentées deux fois déjà. Herb Sutter parle ensuite d'applications qui exploitent les coroutine pour masquer la latence de la mémoire, ce qu'il estime remarquable. Enfin, Herb Sutter rappelle que l'implémentation pour Clang est aujourd'hui meilleure que celle, originale, de Microsoft, ce qui lui semble être remarquable

Geoffrey Rohmer fait remarquer que n'importe quelle proposition alternative sera, presque par définition, moins mature que l'originale. Il souhaiterait savoir à quelle hauteur se trouve la barre pour une éventuelle réplique

Bjarne Stroustrup livre un plaidoyer pour se tenir à jour, la TS étant sur la table depuis longtemps. Ville Voutilainen mentionne que l'absence de types standards existants dans la TS a ralenti sa compréhension. Chandler Carruth rappelle que Geoffrey Rohmer ne veut pas livrer une proposition concurrente, mais bien raffiner la proposition existante. DSankel irait de l'avant malgré les défauts de ce qui est sur la table

Ville Voutilainen propose des votes, l'un étant pour la fusion de la TS à C++ 20 et l'autre étant pour la poursuite du travail sur la TS

Geoffrey Rohmer pense que nous avons déjà les coroutine étant donné la TS, qui est une entité bien réelle. Il les veut aussi, mais je pense pas que les avoir dans l'IS soit nécessaire

Aaron Ballman demande ce qu'une nouvelle révision de la TS nous apporterait comme information quantifiable. Ville Voutilainen dit qu'il va un peu à la pêche avec ses options de vote

Bjarne Stroustrup parle de l'importance d'avoir de l'expérience concrète sur des implémentations portables

Herb Sutter dit qu'ils souhaiterait que, si la pièce souhaite une poursuite de la TS, on vise tout de même C++ 20

Ville Voutilainen rappelle qu'adopter les coroutine dans l'IS ne signifie pas cesser de travailler pour l'améliorer

David Herring : si nous n'avions pas de TS mais voulions une implémentation de qualité, nous devrions quand même nous entendre sur quelque chose pour avancer

Ville Voutilainen rappelle l'inportance d'avoir les coroutine dans le WD pour avoir le support plein et entiers de LWG

Torvald Riegel mentionne que SG1 envisage des TS qui se réfèrent entre elles. Il pense aux exécuteurs

Herb Sutter dit que c'est aussi arrivé avec les concepts et les intervalles

Le vote (informel) est pris. L'intégration immédiate ne passe pas, mais les retouches en vue d'une intégration maintenue vers C++ 20 rencontrent un assentiment très fort. C'est déjà ça : les gens veulent les coroutine, mais il y a des craintes sur le texte existant

Gabriel Dos Reis souhaite une indication du temps restant pour livrer. Herb Sutter dit avoir sondé les NB avant le début de cette semaine et ne pas être surpris du résultat. Gabriel Dos Reis craint que l'on ne pellete le tout par en avant encore une fois à Rapperswil. Herb Sutter dit que les NB ont des points précis sur lesquels ils souhaitent voir la situation progresser. Ville Voutilainen parle de l'importance d'arriver avec des ajustements concrets et sérieux à la prochaine rencontre

Herb Sutter recommande aux gens de bâtir du consensus bien avant la date limite pour livrer une proposition en vue de Rapperswil. Mike Miller indique que CWG retourne à ses travaux. Il est environ 16 h 50

Nous nous déplaçons d'un local à l'autre. Les discussions de corridor sont un peu rudes; ce fut tendu sur le plan de la procédure.

Mike Miller annonce ce que nous ferons pour la prochaine demie-heure

Layout-compatibility and Pointer-interconvertibility Traits – P0466R1

Lisa Lippincott explique qu'il s'agit d'une proposition destinée à LWG, comprenant des traits comme is_layout_compatible_v<T,U> et is_corresponding_member_v dans l'optique de savoir si deux pointeurs sont inter-convertibles

Hubert Tong dit que le terme pointer-interconvertible n'est pas le bon ici

Lisa Lippincott dit qu'elle n'est pas d'accord, et mentionne le common initial sequence et la relation avec le layout des objets

Jason Merrill dit que ce terme réfère à la relation entre objet contenu et objet englobant

Lisa Lippincott dit que la relation est transitive et fonctionne selon elle

Gabriel Dos Reis se demande si EWG a été consulté

Lisa Lippincott dit avoir consulté Herb Sutter qui lui a suggéré de passer directement par LWG

Jens Maurer pense aussi que les concepts décrits ne sont pas reliés

Lisa Lippincott décrit is_layout_compatible<T,U> qui correspond à un concept de niveau langage et requiert un support intrinsèque pour être implémentable

Jens Maurer demande si les types impliqués doivent être complets. Lisa Lippincott pense qu'il existe déjà de la terminologie pour indiquer que les types doivent être complets. Hubert Tong mentionne que LWG saurait

Hubert Tong pense que les cas de multiples classes de base n'est pas suffisamment couvert

Richard Smith pense que is_initial_base_of est au moins en partie redondant désormais (dans sa définition, ce trait décrit une relation de pointer-interconvertibility)

Lisa Lippincott décrit ensuite is_initial_member. Jens Maurer demande une description plus formelle des types. On travaille la formulation. Richard Smith propose de l'exprimer sous forme d'une fonction constexpr plutôt qu'un trait. Gabriel Dos Reis pense ici encore qu'EWG devrait y jeter un coup d'oeil d'abord, surtout pour s'assurer que le volet stylistique soit en accord avec les pratiques contemporaines, surtout à la lueur de la réflexivité statique

Mike Miller remarque qu'un exemple proposé est brisé, mais Hubert Tong constate qu'il fonctionne... mais c'est extrêmement subtil. Je viens d'apprendre quelque chose :

struct A { int a };
struct B { int b };
struct C: A, B {};
static_assert( is_initial_member_v< &C::b > );   // succeeds!
// subtilité : &C::b est de type int B::*, et non pas de type int C::*

John Spicer demande une précision sur les dérivés directs ou indirects et le comportement des traits proposés

Patrice Roy souligne que dans struct A{}; struct B{}; struct D:A,B{}; on aura is_initial_base_of_v<A,D>&&is_initial_base_of_v<B,D>

On doit fermer pour la journée (du moins d'ici le début de la séance de soirée). Lisa Lippincott demande quelle est la guidance de CWG, ce qui est précisé. Jens Maurer recommande un retour plus tard cette semaine avec terminologie retouchée

Je me retire dans ma chambre pour poursuivre la préparation de mon (bref) exposé de ce soir.

En relisant les informations à ma disposition et en prenant connaissance des derniers messages de l'auteur, je me suis aperçu que je serais dans le pétrin : défendre correctement la proposition aurait demandé beaucoup de pédagogie, de schémas, mais il est devenu clair que, sur la base des spécifications, je ne serais pas arrivé à écrire moi-même une version satisfaisante de slot_map.

Expliqué autrement, je comprenais bien les forces et les faiblesses, mais je n'étais pas en mesure d'en expliquer les subtilités. Les raisons étaient d'ailleures claires : plusieurs questions de fond étaient encore obscures pour l'auteur lui-même. J'ai donc dû me résoudre à faire une présentation en surface.

La soirée s'est bien déroulée dans l'ensemble... sauf pour moi. Cinq conteneurs étaient présentés, et j'aurais pu expliquer sans peine trois d'entre deux (trois et demie, en fait). Nicolai Josuttis, en particulier, a fait un travail remarquable avec colony (bravo!). J'ai essayé de rapiécer ensemble quelques schémas pour aider ma proposition douloureuse, mais rien de satisfaisant ou que j'aurais moi-même préparé comme tel. Je me suis donc présenté devant la foule avec quelque chose de boiteux et qui ne rendait pas justice à ce que je devais défendre. Mon erreur fut d'accepter de le défendre sans vérifier que c'était prêt à être présenté, mais c'est mon erreur et j'aurais dû le faire.

L'audience a été gracieuse, mais ce fut un désastre.

Il demeure que beaucoup de bien découlera de cette soirée : les quatre autres conteneurs ont été bien reçus, et il y a possibilité d'un véhicule alternatif que le standard pour ce que j'ai mal défendu.

Je suis revenu à ma chambre pour absorber le coup, prendre soin de m'excuser auprès de l'auteur et féliciter mes collègues qui ont fait un excellent travail.

Je me sens bien loin de mon amoureuse ce soir...

Jour 2 14 mars 2018

Commençons la journée par quelque chose d'important : un bel et bon anniversaire à ma chic maman Lucille, qui rajeunit plutôt que vieillir.

Pour les autres, bon jour de π

Levé à 4 h 55 ce matin. Douche, café, retour de courriels, etc. Je réponds à quelques questions d'étudiant(e)s, je gère quelques dossiers pressants. Je contacte aussi Marius Bancila, dont j'avais accepté de présenter la proposition pour un std::uuid; je l'informe de ma mauvaise prestation d'hier soir mais je l'assure que je ne suis pas toujours aussi mauvais. Je l'informe aussi de ce dont Titus Winters nous a parlé hier soir : LEWG est débordé de travail et ne pourra pas traiter la moitié des propositions soumises cette semaine, alors il se peut que sa proposition ne puisse être traitée. Je lui suggère des véhicules alternatifs pour ses idées, le cas échéant. Je m'assure aussi de bien maîtriser sa proposition et voir venir les coups (trucs à préciser, questions possibles du public), pour éviter un autre fiasco si jamais je dois présenter le tout (Titus Winters m'informe qu'il y a une mince possibilité qu'on y arrive).

J'apprends par Guy Davidson que SG1 compte examiner de plus près son ring_span (qui change de nom à chaque rencontre depuis deux ans, et en est à sa sixième révision; c'est pas la faute du pauvre Guy Davidson, qui fait de l'excellent travail). Guy Davidson semble ravi... et moi aussi!

Je me prends un muffin et un café, puis direction CWG pour les travaux de la journée.

Nous recevons un courriel de Herb Sutter en début de journée, indiquant la chronologie attendue des événements importants en vue de C++ 20, incluant les composants majeurs (réflexivité statique, modules, contrats, coroutines) sur lesquels nous ne nous sommes pas encore pleinement entendus (pour les concepts, autre truc majeur, nous savons maintenant pas mal ce qui sera intégré au standard). Cette chronologie met en relief les dépendances, pour qu'on sache ce qui doit absolument être réglé dans la prochaine année (en particulier, les exécuteurs desquels plusieurs mécanismes clés dépendent).

Les modules sont discutés chez EWG ce matin, alors quelques-uns de nos participants habituels seront là.

Selon la tradition, c'est le Inappropriate Tee-Shirt Day. Il me faudrait vraiment un chandail de Java ou de C# pour le prochain meeting... On a un peu de tout ici : Visual C++, Facebook, un ancien commanditaire, etc. tous portés par des compétiteurs.

Mike Miller accueille Thomas Köppe, qui présentera deux propositions assez courtes de Ville Voutilainen

Relaxing the structured bindings customization point finding rules – P0961R0

Thomas Köppe : les règles actuelles pour get sont trop agressives, et couvrent des cas qui ne sont pas des templates. La proposition est de restreindre un peu le tout pour éviter des situations comme la suivante :

#include <memory>
#include <tuple>
#include <string>
struct X : private std::shared_ptr<int> {
   std::string fun_payload;
};
template<int N> std::string& get(X& x) {
   if constexpr(N==0) return x.fun_payload;
}
namespace std {
   template<> class tuple_size<X> : public std::integral_constant<int, 1> {
   };
   template<> class tuple_element<0, X> {
   public:
      using type = std::string;
   };
}
int main() {
   X x;
   auto& [y] = x; // présentement, malformé, même si on a fait l'effort de placer des spécialisations pour X&
}

On est d'accord avec la formulation adaptée proposée, qui demande un get avec un premier paramètre qui serait un non-type, ce qui couvre template<auto> et d'éventuels template<auto,class...> au passage. Thomas Köppe ira vérifier un truc, mais ça semble propre. Ce serait un DR sur C++ 17

Relaxing the range-for loop customization point finding rules – P0962R0

Encore une fois, le changement est mineur mais corrige un irritant, comme dans le cas :

#include <sstream>
#include <iterator>
struct X : std::stringstream {
   // some other stuff here
};
std::istream_iterator<char> begin(X& x) {
   return std::istream_iterator<char>(x);
}
std::istream_iterator<char> end(X& x) {
    return std::istream_iterator<char>();
}
int main() {
   X x;
   for (auto&& i : x) { // malformé dû à un oubli
      // do your magic here	      
   }
}

Ce serait un DR sur C++ 17. Ville Voutilainen pense qu'on devrait recommander aux vendeurs de l'appliquer à toutes les versions des compilateurs depuis C++ 11; Thomas Köppe ajoute une recommandation éditoriale au texte proposé; la formule est très générale : "The wording changes are intended as a defect report and should be applied in implementations of all previous revisions of the Standard where they apply"

Allow structured bindings to accessible members – D0969R0

Hubert Tong exprime une surprise à la vue d'un document 'D' avec un 'R0', qui est la forme sous laquelle ce document se trouve chez EWG

Timur Doumler vient nous le présenter. C'est sa première expérience chez CWG

Timur Doumler explique un problème que j'ai moi-même rencontré récemment : les Structured Bindings fonctionnent sur la base des attributs publics, pas sur la base de l'accessibilité au point d'utilisation

Hubert Tong dit que c'est un enjeu de perspective; selon lui, les Structured Bindings sont un concept plus près de celui d'un agrégat. Timur Doumler voit plutôt les Structured Bindings comme une manière de nommer les éléments constitutifs plutôt que de nommer l'objet englobant. Patrice Roy rappelle sa propre expérience toute récente : pour un objet, être incapable d'appliquer un Structured Bindings à l'intérieur d'une méthode d'instance sur ses propres attributs parce qu'ils sont privés est... surprenant

Patrice Roy demande si ce sera un DR sur C++ 17. Timur Doumler dit que chez EWG, on a choisi de le traiter comme un DR et non pas comme un changement de design. Puisque ce sera la dernière révision technique de ce document avant adoption, Jens Maurer demande d'insérer le texte à cet effet à même la proposition

Hubert Tong soulève une préoccupation, pas sur le mécanisme mais sur la formulation. Le mot accessible s'applique aux noms et aux lieux de références en C++, et il n'est pas à l'aise avec une formulation trop informelle. Il suggère une tournure plus précise, qui évitera entre autres de mal gérer les attributs publics de parents publics et autres étrangetés du même acabit. Mike Miller propose une formulation inspirée de ce qu'on trouve dans §14, http://eel.is/c++draft/class.access, ce qui semble inspirant

Hubert Tong y va de "Otherwise, all of these non-static data members shall be direct members of E or of the same base class of E, well-formed when named as e.name in the context of the structured binding" ce qui commence à ressembler à quelque chose de formel (le lien entre E et e est tissé par le contexte plus complet, qui inclut le reste du paragraphe)

Pour le reste, on travaille la ponctuation pour ne pas être noyés dans les virgules

Thomas Köppe a, entre-temps, raffiné la terminologie pour évoquer un DR sur C++ 17. Il la partage : "The reported issue is intended as a defect report with the proposed resolution as follows. The effect of the wording changes should be applied in implementations of all previous versions of C++ where they apply". On propage le tout aux divers documents visés

On en fera une Core Motion samedi

Add symmetric coroutine control transfer – P0913R0

Mike Miller vérifie auprès de Gor Nishanov si ça devrait être une Core Motion ou une Library Motion. Gor Nishanov pense que Library est le bon véhicule pour ceci

Gor Nishanov explique le mécanisme, qui constitue une importante optimisation dans certains cas d'utilisation pour les coroutines

Jens Maurer pense que la mention "Implementations shall not impose any limits on how many coroutines can be resumed in this fashion" devrait disparaître, relevant de la qualité d'implémentation. John Spicer suggère une note non-normative indiquant qu'un nombre non-plafonné de coroutines peuvent être résumées ici. Hubert Tong pense que du texte normatif est préférable. On débat du seuil auquel le texte devrait être directif (ou pas). On finit par converger sur une note non-normative

Jens Maurer demande de clarifier le caractère successif des résomptions. Patrice Roy demande pourquoi la contrainte doit être inscrite dans le texte plutôt que laissée à la liberté de l'implémentation, mais Gor Nishanov dit que ce côté successif est bel et bien ce qui est souhaité

On y reviendra une fois les retouches faites

Add parameter preview to coroutine promise constructor – P0914R0

Gor Nishanov explique qu'il s'agit d'un mécanisme pour injecter certaines objets influençant le contrôle de l'exécution d'une coroutine au moment de leur construction. Pour l'instant, il y a des voies de contournement avec certains compilateurs, mais celles-ci ne fonctionnent pas à niveau d'optimisation élevé

Brève pause à 10 h 15.

On poursuit les travaux

Add parameter preview to coroutine promise constructor – P0914R0 (suite)

Aaron Ballman se dit préoccupé par la terminologie proposée, qui ressemble dans sa forme à des productions grammaticales (un indice opt apparaît dans le pseudocode)

Jens Maurer suggère de simplifier la formulation pour exploiter ce que nous avons pour les paramètres variadiques. Gor Nishanov estime qu'il faudra alors ajouter un ajustement de conformité avec operator new

Jens Maurer pense que l'ajout d'un constructeur aux promesses des coroutines risque de briser du code existant. On réfléchit à la gestion des possibles cas d'erreurs dans le cas de multiples constructeurs possibles pour une situation donnée; il y a une situation un peu différente des cas habituels d'overload resolution ici, pour des raisons techniques : les texte proposé indique "If a matching constructor is found, then promise-constructor-arguments is (p1,...,pn), otherwise promise-constructor-arguments is empty" mais on comprend que le otherwise ne dit pas ce qu'il devrait dire si on veut une erreur de compilation

Hubert Tong pense que le terme viable constructor est ce qui nous amènera à la bonne séquence d'étapes pour le comportement souhaité, donc "If a viable constructor is found, then promise-constructor-arguments is (p1,...,pn)"

Gor Nishanov aura besoin de temps pour faire les changements. On le reverra plus tard

Rebase the Coroutines TS onto the C++17 Standard – P0911R0

Gor Nishanov présente les changements d'identification des sections et autres retouches requises pour respecter l'évolution du document et suivre le nouveau format exigé par ISO. Les retouches les plus importantes sur le plan terminologique apparaissent dans la section sur return et co_return, de même que les productions grammaticales qui les utilisent

Jens Maurer remarque une incohérence entre la grammaire discutée ici et celle décrite dans §6.6.3.1 de la TS

Thomas Köppe fait remarquer qu'il y a une incohérence similaire dans un autre document de référence

Gor Nishanov va nous revenir

Relaxing the structured bindings customization point finding rules – P0961R0

Thomas Köppe : EWG ne souhaite pas un Breaking Change ici

Hubert Tong : il y a un risque de conflit avec les références sur des globaux ou avec les pointeurs ici. On espère éviter d'énumérer les cas possibles

Thomas Köppe suggère une tournure reposant sur tout non-type, ce qui aurait le mérite de ne rien briser

Hubert Tong fait remarquer que certaines énumérations ne sont pas nécessairement des entiers au sens strict du terme dans son acception grammaticale

John Spicer dit qu'il aurait été à l'aise de n'accepter que auto et les entiers, quitte à briser quelques trucs

Jens Maurer dit que la conversion d'enumération classique à entier est implicite

Thomas Köppe fait remarquer que les concepts pourraient se glisser ici, ce qui demande un peu de prudence

Thomas Köppe constate qu'on pourrait même contraindre, par voie de concepts, aux entiers pairs par exemple

Hubert Tong propose une formule reposant sur l'idée de placeholder type qui semble fonctionner

Jason Merrill propose une approche conservatrice, soit l'utilisation de non-type template parameter tout simplement. Thomas Köppe fait remarquer que ça ouvre à la porte à des extensions créatives

Mike Miller fait remarquer que Core Issue 2339 dit que le type de I dans get<I>(tup) est std::size_t. Un ajustement est suggéré pour harmoniser le tout

John Spicer préfère la forme générale de non-type template parameter

Hubert Tong fait remarquer que les gens utilisent souvent int, ce qui poserait problème

Thomas Köppe rappelle la démarche : on exclut des options ce qui ne colle pas, mais on évite ensuite d'explorer des options qui seraient indésirables

On va l'amener pour vote samedi

On suspend les travaux vers midi. Les débats sur les modules chez EWG se sont poursuivis tout l'avant-midi et se poursuivront manifestement cet après-midi aussi. J'ai bien hâte de savoir ce qui va en découler. J'ai profité du dîner pour avancer dans ma correction d'essais et correspondre un peu avec mon amoureuse.

Je tiens le Wiki en début d'après-midi pendant que Jens Maurer présente une proposition devant EWG. Ceci explique le style différent (et le recours à l'anglais) dans ce qui suit.


P0528R1 The Curious Case of Padding Bits, Featuring Atomic Compare-and-Exchange (JF Bastien et al)

P0634R2 Down with `typename`! (Nina Ranns et al)

D0780R2 Allow pack expansion in lambda init-capture (Barry Revzin)

D0194R6 Static reflection (Matúš Chochlík et al)

Pause vers 15 h 32. Je remets le contrôle du Wiki à Jens Maurer une fois les derniers ajustements terminés. Malheureusement pour moi, j'arrive trop tard pour manger une bouchée, la nourriture était disparue.

Je croise Gabriel Dos Reis qui m'informe que la rencontre de SG12 prévue demain matin sera remise à la rencontre de Rapperswil, faute d'avoir une pièce pour se rencontrer. Je bavarde aussi avec JF Bastien de trucs intéressants mais dont je ne peux pas parler encore (na, na!)

Vittorio Romeo se joint à nous pour vivre « l'expérience CWG »

Mike Miller suggère que l'on aborde des Core Issues de priorité 1. Jens Maurer souhaite aussi traiter quelques Core Issues de nature éditoriale

2118. Stateful metaprogramming via friend injection

Jens Maurer suggère d'écrire une proposition pour interdire ceci

Vittorio Romeo demande pourquoi nous l'interdirions

Jens Maurer : nous ne sommes pas d'avis que ce soit le chemin à encourager pour le développement de techniques de Stateful Metaprogramming. Ce n'est pas particulièrement portable, et nous ne sommes pas convaincus qu'il soit raisonnable de les contraidre à y arriver. Un mécanisme pensé pour cette fin nous semble préférable

Hubert Tong : nous pensons que changer le sens d'un nom en le faisant réévaluer plusieurs fois est un effet accidentel, mais il nous manque les mots pour prévenir cet accident

2202. When does default argument instantiation occur?

Nous avons divergence d'implémentation sur la base du texte suivant : « If a function template f is called in a way that requires a default argument to be used, [default argument instantiation is performed] ». Quel sens donner à un cas comme le suivant?

#include <type_traits>
template<class T> struct Foo { Foo(T = nullptr) {} };
bool b = std::is_constructible<Foo<int>>::value;
int main() {
}

C'est une Issue de Richard Smith. On attendra son retour

2335. Deduced return types vs member types

Que faire de ceci?

 template <class ...> struct partition_indices {
    static auto compute_right () {}
    static constexpr auto right = compute_right; // ici, maintenant...
  };
  auto foo () -> partition_indices<>;
  void f() {
    foo();
  };

John Spicer : il me semble étrange qu'on puisse instancier quelque chose avant la fin de sa classe. Je me suis amusé avec plus ou moins de trucs dans la classe, et les résultats varient beaucoup. Ici, right pointe sur compute_right qui ne devrait pas pouvoir être référencé, n'existant pas.

Jason Merrill : g++ a une bogue dans ce cas. Nous déduisons pointer de fonction retournant auto, puis nos avons un problème avec une conversion de pointeur de fonction retournant void... C'est un tout autre dossier.

John Spicer : les règles sans templates sont claires

Jens Maurer : faudrait pas que le cas avec template diverge trop du cas sans template

John Spicer : je suis ouvert à écrire quelque chose, si on s'entend sur ce qu'on veut dans ce cas

Faisal Vali : n'a-t-on pas d'autres cas semblables avec constexpr? Pour déterminer une taille de tableau par exemple...

John Spicer : je m'en occupe

2317. Self-referential default member initializers

Cette horreur :

struct A {
   int n = A{}.n;
}; 

Richard Smith indique que nous avons des mécanismes pour éviter des horreurs récursives infinies dans certains cas, mais faudrait une solution générale.

Roger Orr : le problème est de savoir à quel point c'est difficile en général, avec des templates

Mike Miller : Hubert Tong avait un plan de match à Toronto

Hubert Tong s'en occupe

Patrice Roy : avec des templates, risque-t-on de créer une récurrence cyclique infinie?

Jens Maurer : la bonne nouvelle est qu'avec des templates, il y a une limite de profondeur d'instanciations

Faisal Vali : ici, on peut construire le cas récurrent parce que le nom a été introduit

Jens Maurer : que veut-on interdire ici?

Hubert Tong : le problème est dans le default initializer

Jens Maurer : on pourrait éviter le débordement de pile en incrémentant une variable globale...

Roger Orr : si un autre constructeur initialisait n, on pourrait être créatif

John Spicer : on peut interdire les accès directs ou indirects au même attribut

Patrice Roy : ça fonctionnerait même avec []{ return A{}.n; }()

Jens Maurer : on pourrait se baser sur le texte sur les références

Faisal Vali : et si on a un A* et un new? Il y a plusieurs manières d'en arriver à des horreurs infiniment récursives

Jens Maurer : je peux simplement ajouter un exemple disant de ne pas le faire

2310. Type completeness and derived-to-base pointer conversions

Richard Smith rapporte qu'on a divergence entre implémentations avec ceci :

template struct check_derived_from {
   static A a;
   static constexpr B *p = &a;
};
struct W {};
struct X {};
struct Y {};
struct Z : W,
  X, check_derived_from<Z, X>, // #1
  check_derived_from<Z, Y>, Y { // #2
  check_derived_from<Z, W> cdf; // #3
}; 

Jason Merrill : ça dépend du point où le type est considéré instancié

Jason Merrill : où considère-t-on une classe parent complète?

Jens Maurer : le problème n'est-il pas l'enfant?

Jason Merrill : c'est plus subtil ici. La question des de voir où est provoquée l'instanciation du type

John Spicer : les conversions parent-enfant ne devraient pas être permises avant que les classes ne soient définies

Faisal Vali : nous avons complet, indéfini et incomplet pour une classe

Jason Merrill : dans l'état de la grammaire que nous avons, nous accumulons des états à propos de la classe alors que nous progressons dans la consommation de sa déclaration

Jens Maurer : aurait-on la capacité de réagir si nous utilisions dynamic_cast? Je sais que ce n'est pas constexpr...

Hubert Tong : il n'y a pas de contexte d'exécution à ce moment

Jens Maurer : si on enlève constexpr?

Hubert Tong : les initialisations peuvent être faites de manière paresseuse

Jason Merrill : pourquoi initialise-t-on la variable constexpr tout de suite?

Hubert Tong : on pourrait reproduire le problème par d'autres moyens

Jason Merrill : je pense que #3 devrait être valide, pas les autres

Faisal Vali : oui, on a l'information suffisante à ce point

Jens Maurer demande si on peut jouer avec les qualifications d'accès, mais Mike Miller nous dirige vers cet exemple :

class A {
   typedef int I; // private member
   I f();
   friend I g(I);
   static I x;
   template<int> struct Q;
   template<int> friend struct R;
protected:
   struct B { };
};
A::I A::f() { return 0; }
A::I g(A::I p = A::x);
A::I g(A::I p) { return 0; }
A::I A::x = 0;
template<A::I> struct A::Q { };
template<A::I> struct R { };
struct D: A::B, A { };

... qui démontre que les qualifications d'accès sont en quelque sorte... rétroactives. En particulier, observez les parents de la classe D...

Jason Merrill : je ne veux pas commencer à contraindre les implémentations sur le positionnement des classes parents dans un enfant.

Faisal Vali : même avec CRTP, on n'a jamais vraiment à convertir le l'enfant en parent quand la classe enfant n'est pas encore complète

Jason Merrill : si j'ajouter un tableau de taille p-p à checked_derived_from, alors g++ refuse les cas #1 et #2

Mike Miller : à cause de p ou de la taille nulle?

Jason Merrill : à cause de p

2308. Structured bindings and lambda capture

Mike Miller : la question posée est de savoir si on le permet. Si oui, c'est un cas de NAD

Vittorio Romeo : c'était pour les paramètres de fonctions

Hubert Tong : EWG en a-t-il parlé?

Jens Maurer : je ne pense pas

Mike Miller : la proposition P0588 permet explicitement de capturer les entités locales, ce qui inclut les Structured Bindings

Jens Maurer : le cas intéressant est celui de la capture par valeur; par référence, c'est bien défini

Jens Maurer : ma vision est que nous copions les membres, pas l'objet englobant

Jens Maurer : je pense que c'est un Design Change. Pour CWG, c'est NAD; s'il y a lieu de la revisiter, c'est chez EWG que ça devrait se faire

2306. Nested friend templates of class templates

John Spicer : quoi faire de ceci?

//
// The current wording is not clear how to declare
// that a nested class template of a class template
// is a friend of its containing template. For example, is

template <class T> struct C {
   template <bool b> class Foo;
   template <bool b> friend class Foo;
}; 
//
// correct, or should it be
//
template <class T> struct C {
   template <bool b> class Foo;
   template <class X> template <bool b> friend class C<X>::Foo;
}; 

Ben Saks demande des précisions. John Spicer préfère y réfléchir

2303. Partial ordering and recursive variadic inheritance

Quoi faire de ceci?

template <typename... T>              struct A;
template <>                           struct A<> {};
template <typename T, typename... Ts> struct A<T, Ts...> : A<Ts...> {};
struct B : A<int> {};

template <typename... T>
  void f(const A<T...>&);

void g() {
  f(B{});
} 

Pour le moment, c'est ambigu. Qui devrait gagner : A<> ou A<int>?

Jens Maurer nous indique qu'on peut lever l'ambiguïté dans certains cas, comme préférer le parent le plus proche plutôt que le plus lointain, mais pas en général

2281. Consistency of aligned operator delete replacement

On doit être tolérants à la bêtise avec les formes plus anciennes de surcharge d'operator delete, mais on peut être stricts avec les nouvelles. Il n'y a pas de raison de ne pas imposer la forme alignée d'operator delete pour appeler lors d'un échec à la construction d'un objet construit avec la forme alignée d'operator new

Jason Merrill s'en occupe

2278. Copy elision in constant expressions reconsidered

Richard Smith fait remarquer que nos règles demandent parfois l'impossible, comme NRVO dans ce cas-ci :

struct B { B *self = this; };
extern const B b;
constexpr B f() {
  B b;
  if (&b == &::b) return B();
  else return b;
}
constexpr B b = f(); // is b.self == &b? 

Jason Merrill : en retournant B(), nous ne pouvons appliquer NRVO

Hubert Tong : on pourrait déterminer que return B() est inatteignable à la compilation

Jason Merrill : Richard Smith nous rappelle le caractère obligatoire de NRVO... même si c'est inimplémentable

Hubert Tong : ici, le return B() ne change rien à l'obligation de NRVO

Mike Miller : est-on près d'une solution? Il est passé 17 h 30

Hubert Tong : le problème est qu'on a un paradoxe dans la condition si on applique NRVO

Jason Merrill : le deuxième return empêche g++ de faire NRVO

Jens Maurer : il faudra peut-être bloquer NRVO dans un contexte constexpr

Hubert Tong : c'est pas une optimisation dans ce cas

On s'entend. Jens Maurer s'en occupe

On ferme vers 17 h 37. Je reviens à ma chambre manger un peu de fromage et quelques crudités, puis bavarder avec les enfants les plus jeunes (Vayda et Ludo) qui ont accès à Skype. Quelques courriels plus tard, me voilà de retour.

Il y a trois séances de soirée concurrentes ce soir : une sur Unicode, une pour classer des LWG Issues, et une pour la réflexivité statique. J'y vais pour la dernière, mais les trois sont tentantes.

Je ne laisserai pas beaucoup de traces ici car j'étais le scribe de la soirée. En gros :

Tout s'est bien passé, c'était intéressant, et tout ce qui a été proposé a reçu un accueil favorable

De retour à mon bureau : une bière, bavardage avec mon amoureuse, traitement de courriels... et dodo

Jour 3 15 mars 2018

Je ne suis pas parvenu à me lever avant 6 h 55 ce matin, malgré le réveil qui a fait tout en son pouvoir pour me tirer du lit à partir de 5 h. J'ai pris ma douche, je me suis rasé (ça commençait à devenir pressant), et j'ai rapidement réglé quelques urgences, mais sans plus. Ici, tout le monde est au travail plus de 30 à 60 minutes avant le début officiel des travaux (publiquement; le travail en-ligne n'arrête jamais).

Une tempête s'annonce chez SG6 ce matin, avec la proposition controversée de JF Bastien sur la gestion du débordement sur un entier signé. La salle est pleine; je vais laisser Richard Smith, Aaron Ballman et Hubert Tong me faire un rapport, et travailler chez CWG

Gor Nishanov est parmi nous alors nous commençons par examiner les changements qu'il a apportés

Add symmetric coroutine control transfer – P0913R0 (suite)

Gor Nishanov explique les changements apportés à la plus récente version. Plusieurs sont cosmétiques (mais ça compte)

Jens Maurer suggère un ajustement à la formulation décrivant le comportement attendu lorsqu'une coroutine redonne le contrôle au code appelant. Ceci suit une remarque par Ben Saks qui n'était pas convaincu de bien comprendre l'intention. Il faut comprendre qu'une interprétation susceptible de varier selon les implémentations serait singulièrement ... déplaisante

On amène ça en plénière samedi

Add parameter preview to coroutine promise constructor – P0914R0 (suite)

Gor Nishanov explique les changements apportés à la plus récente version. Plusieurs sont cosmétiques (mais ça compte, encore une fois)

Mike Miller remarque un détail mineur (un espace dans une modification qui laisse une ambiguïté visuelle sur la présence ou l'absence d'un caractère de soulignement dans le code)

Jens Maurer suggère l'ajout d'une référence croisée pour faciliter la lecture

On amène ça en plénière samedi

Rebase the Coroutines TS onto the C++17 Standard – P0911R0 (suite)

On identifie des mots manquants

Gor Nishanov a eu des ennuis avec son document Markdown et sa transformation éventuelle à html. C'est à retenir pour le futur : avec nos insertions / suppressions et le suivi des changements qui doit être fait dans les documents, l'expérience Markdown n'est peut-être pas un succès

Mike Miller constate un changement à §21, ce qui entraîne la question de savoir si LWG a vu le document. Semble que non. Jens Maurer pense que CWG devrait amener ce document en plénière puisque la majorité des changement sont du côté Core Language

On amène probablement ça en plénière samedi, en fonction de ce que LWG nous dira

2335. Deduced return types vs member types (revisité)

Jason Merrill a implémenté la résolution hier et ça brisait du code important

Patrice Roy a écrit qu'il estimait que le changement entraîné par la résolution est trop vaste

John Spicer pense qu'on devrait l'implémenter quand même, et laisser les gens contourner les ennuis que ça leur cause (il existe des voies de contournement)

John Spicer explique ce qu'il pense qu'on devrait écrire comme terminologie pour permettre de raffiner le modèle préconisé. Par exemple, on ne peut pas, dans une méthode constexpr de classe de X définie à même le corps de la classe, instancier X du fait que X n'est pas complet à ce stade

Jens Maurer demande si le comportement est influencé par le caractère générique ou pas du contexte. Jason Merrill dit que oui; dans un des cas, le traitement est traité de manière paresseuse

Patrice Roy insiste sur le fait que ce sera dur à vendre comme argumentaire aux usagers

John Spicer prend cela sur la perspective des étapes de génération du code. Pourquoi le langage serait-il différent pour un template et pour un non-template?

Jason Merrill dit que l'évaluation des templates est un peu plus du style juste-à-temps

Jens Maurer pense qu'on peut trouver une manière de permette le cas irritant

Pour le cas sous examen ici, Jason Merrill pense qu'initialiser right implique instancier compute_right. John Spicer pense que g++ y arrive dû à un bogue de nom-conformité au standard

Jens Maurer pense que les fonctions auto et les fonctions constexpr partagent la caractéristique d'être dans la catégorie delayed parse

John Spicer dit que dans ce cas, il faut des règles pour préciser ce qui peut être fait, ou pas

Jens Maurer pense qu'une forward reference n'est pas acceptable. Si on veut des dépendances, faudrait par contre imposer une lecture séquentielle, comme dans le cas des types

John Spicer dit que ça a des conséquences sur d'autres bibittes comme les paramètres par défaut et les qualifications noexcept

Jason Merrill se dit sceptique. Ça lui semble être un gros défi, pour un truc qui n'était techniquement pas supporté par le passé

Mike Miller pense que le traitement de ces deux cas devrait découler du traitement normal des templates

Mike Miller demande si on devrait aller devant EWG. Jason Merrill dit que si on va dans cette direction, ça serait la chose à faire (si on décide de ne pas aller là, c'est autre chose)

John Spicer suggère qu'on en parle avec Richard Smith d'abord. Ça peut avoir des ramifications à plus grande échelle

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

Richard Smith a remarqué une incohérence apparente entre les accolades et les parenthèses, à propos des conversions par voie d'opérateur de conversion ou par voie de construction :

struct A {} a;
struct B { explicit B(const A&); };

struct D {};
struct C { explicit operator D(); } c;

B b1(a); // #1, ok
const B &b2{a}; // #2. ok
const B &b3(a); // #3, error ... pourquoi?

D d1(c); // ok
const D &d2{c}; // ok
const D &d3(c); // #6, ok ... alors que #3 ne l'est pas...

Jens Maurer se dit troublé. Jason Merrill dit que g++ rejette à la fois #3 et #6. Daveed Vandevoorde pense que les cas #2, #3, #5 et #6 devraient tous échouer, mais est d'accord pour dire que #3 et #6 devraient être traités de la même manière, peu importe laquelle

Richard Smith se demande si EWG accepterait un ajustement aux règles existantes pour que le comportement soit plus homogène entre les cas #3 et #6

Jens Maurer indique qu'il lui semble plausible d'appliquer copy-initialization pour réaliser un binding avec une const&. Après tout, ça évite un cas de dangling reference et ça rejoint ce qu'on fait avec le passage de paramètres

On en jase, et on en vient à la conclusion que #2, #3, #5 et #6 devraient tous échouer, comme le suggère Daveed Vandevoorde. Mieux vaut éviter de créer des copies non-sollicitées

Jason Merrill nous dirige vers §11.6.4. Il voit aussi un lien avec Core Issue 1494. Temporary initialization for reference binding in list-initialization, qui a été résolu en 2013 en tant que DR

Mike Miller demande si on doit renverser la résolution de Core Issue 1494. Jason Merrill préfère qu'on re-résolve le même issue différemment, pour mieux traiter le cas de copy-initialization, et qu'on informe EWG

Jens Maurer va travailler la terminologie, et Mike Miller informera VV

2266. Has dependent type vs is type-dependent

FSergeev amène à notre attention une subtilité dans la définition de types dépendants

Jens Maurer pense que c'est un cas de priorité P0, pas un cas de P1

Richard Smith pense qu'on a un bogue de terminologie dans ce cas

Jens Maurer va s'en occuper

2265. Delayed pack expansion and member redeclarations

Hubert Tong attire notre attention sur un besoin de clarification quant au moment d'instanciation de templates dans des contextes variadiques. Son exemple donne un peu le tournis :

template<typename ...T> struct Tuple; 
template<class T, class U> struct Outer; 
template<class ...T, class ...U> 
struct Outer<Tuple<T ...>, Tuple<U ...> > { 
  template<class X, class Y> struct Inner; 
  template<class ...Y> struct Inner<Tuple<T, Y> ...> { }; 
  template<class ...Y> struct Inner<Tuple<U, Y> ...> { }; 
}; 
Outer<Tuple<int, void>, Tuple<int, void> > outer;

Richard Smith ajoute cet exemple, que les implémentations actuelles trouvent extrêmement déplaisantes (la plupart plantent) :

template<typename ...T> struct Foo {
   template<typename ...U> void Bar(typename T::template X<U>...);
   template<typename ...U, typename V>
      void Baz(typename T::template X<U>..., V);
};

struct Q { template<typename T> struct X {}; };

void x(Foo<Q, Q> foo, Q::X<int> xi) {
   foo.Bar(xi, xi);
   foo.Baz(xi, xi, 0);
}

On va attendre le retour de Hubert Tong et de Richard Smith pour en discuter

2264. Memberwise copying with indeterminate value

Ceci est indéfini en C++... mais pas en C :

struct A { int x, y; };
A passthrough(A a) { return a; }
int main(void) {
   A a;
   a.x = 0;
   return passthrough(a).x;
}

... à cause du membre qui qui n'est pas initialisé avant la copie de a. Sur ce sujet, C est spécifique : "[t]he value of a structure or union object is never a trap representation".

2261. Explicit instantiation of in-class friend definition

Jens Maurer fait remarquer que ceci brise g++ :

struct S {
   template <class T>
      friend void f(T) { }
};
template void f(int); // error: cannot find primary template

(note personnelle : je ne savais pas que c'était supposé être légal, mais les <> ne sont plus nécessaires maintenant quand tous les paramètres requis pour une instanciation sont déduits... Cool! Mais j'ai vérifié et c'est pas encore supporté partout...)

Mike Miller fait remarquer que les règles de lookup ont changé depuis la publication de ce problème

Jason Merrill dit que les règles de lookup lors de redéclarations diffèrent de celles en situation d'ADL

John Spicer dit que pour une spécialisation, ça ne lui semble pas déraisonnable

Jens Maurer voit une différence en fonction du namespace d'où les noms proviennent / où les amis sont définis

On prend une brève pause vers 10 h 15. Je vais me chercher une bouchée. Tout est sucré ici : c'est des brownies, des biscuits, des muffins... Celles et ceux qui me connaissent savent que je ne suis pas nécessairement « de type sucré »; chez CWG, on se garde une réserve de bananes, mais elle commence à baisser... Je dois aller me chercher un nouveau tube de dentifrice ce soir (le mien tire à sa fin; je compte passer à l'épicerie après la réception), je prendrai une douzaine de bananes au passage pour refaire nos stocks.

Le tourbillon autour de la propositon de JF Bastien pour faire des débordements sur les entiers signés quelque chose de défini, et pour imposer par le fait-même une représentation par voie de complément à deux, n'a pas encore débuté. Semble que SG6 compte attaquer ce dossier juste après la pause.

On recommence

2256. Lifetime of trivially-destructible objects

Quand la vie d'un objet sans destructeur se complète-t-elle vraiment? Par exemple :

void f() {
   struct A { int *p; ~A() { *p = 0; } } a;
   int n;
   a.p = &n;
}

Comme l'indique Richard Smith, "According to the current standard, this code has defined behavior. The lifetime of 'n' ends when its storage duration ends (see [basic.life]/1.4), which is after a's destructor runs". L'enjeu est l'interaction entre la mort de n et la mort de a, qui écrit dans n par voie de *p. L'espace alloué pour n existe encore même si n n'existe plus, ce qui est... suspect. Le fait que n n'ait pas de destructeur est une partie de l'enjeu

Jens Maurer s'en occupe, il pense s'en sortir en supprimant des cas particuliers du texte.

2252. Enumeration list-initialization from the same type

On a des bizarreries dans les conversions vers des enumérations fortes :

enum class E {};
struct X { operator E(); };
E{X()}; // ok?

Notez les accolades. Pour ajouter à la bizarrerie :

enum class E {};
struct X { operator int(); };
E{X()}; // ok?

// Here, X() does implicitly convert to E's underlying type, but E(X()) is
// ill-formed. If we view the enum as if it behaved like either
//
//    struct E { underlying_type v; };
// or
//    struct E { explicit E(underlying_type); };
//
// ... then E{X()} should be valid. If we view it as an alternative syntax for
// E(X()), then it should be ill-formed (or perhaps static_cast(X()) should
// be valid). I'm not sure what the right answer is here

Jens Maurer explore la grammaire pour identifier les règles qui s'appliquent

Jason Merrill n'est pas d'accord avec l'exemple, proposé par Richard Smith. Selon Jason Merrill, l'évaluation normale d'un transtypage à E s'applique, et l'absence de conversion signifie que nous n'avons pas de narrowing conversion, il ne nous reste qu'une copie

Mike Miller pense que le premier exemple est NAD

Patrice Roy pense que le deuxième est ill-formed. Jason Merrill aussi. On s'entend pour NAD

2244. Base class access in aggregate initialization

En 2016, Richard Smith a proposé l'exemple suivant :

struct A {
protected:
  A();
};

struct B : A {
  friend B f();
  friend B g();
  friend B h();
};

B f() { return {}; } // ok?
B g() { return {{}}; } // ok?
B h() { return {A{}}; } // ill-formed?

Notez que B n'a pas de constructeur public, et que le constructeur par défaut de A est protected

Jens Maurer fait remarquer que f(), g() et h() sont amis de B. Ça influence le portait

Faisal Vali demande si, en l'absence d'amis, puisque le constructeur par défaut de B est public, f() serait Ok. Tous sont d'accord

Jason Merrill dit que c'est un aggregate-initialization, dû à l'ordre dans lequel les règles sont appliquées présentement. Si f() n'était pas un ami, il ne compilerait pas. La question est de savoir si nous posons les bons gestes

Roger Orr demande si int main() { B{}; } compilerait. Faisal Vali pense que si, mais Jason Merrill n'est pas d'accord (agrégat; ici, B() compilerait par contre). Accepter ou non B{} est un choix esthétique, qui a du bon et du moins bon, mais le standard dans sa formulation existante ne l'accepterait pas pour un non-ami

Jens Maurer nous ramène sur la situation avec amis, qui est sur la table

Jason Merrill pense que h() n'est pas acceptable

Jens Maurer trace un argument quant à l'absence d'un B au moment où le A{} est écrit

Jason Merrill pense qu'on devrait indiquer ce qu'on pense devoir faire, et mettre la rédaction d'une résolution à priorité P2

Mike Miller est d'accord


Jens Maurer aimerait que l'on restructure une partie du standard, ce qui parle de classes, pour que ce soit moins éparpillé. Le standard est sur github en format LaTeX, librement accessible. Plusieurs (Thomas Köppe, Jens Maurer, Richard Smith, etc.) en profitent pour faire du nettoyage

Jens Maurer : le github a un système de Bug-Tracking et permet de faire des branchements sujets à approbation pour fins de fusion dans la branche principale

Jens Maurer : il y a des Core Issues et des Editorial Issues. Il aimerait qu'on aborde quelques Editorial Issues qui ne sont pas assez triviales pour être justement traitées de manière éditoriale. Certains changements méritent peut-être d'être amenés en plénière

Jens Maurer pense qu'on devrait aussi utiliser ce Bug-Tracker comme mécanisme pour les Core Issues de priorité P0, pour accélérer la procédure

[stmt.while] Generalize the equivalence for a declaration as the condition. #1931

Le texte indique "A while statement of the form while (T t = x) statement is equivalent to [...]" mais on peut aussi écrire T t{x} qui ne semble pas couvert par le texte normatif. Jens Maurer ajoute "The existing "of the form T t = x" text also has the problem that "of the form" doesn't fit if T is a function type, i.e. the declarator-id is somewhere nested".

Le changement proposé utilise un exemple qui améliore significativement le texte normatif, mais utilise une variable t qui n'existe que dans le texte normatif, pas dans le texte de l'exemple. Patrice Roy suggère qu'on clarifie ce détail

Jens Maurer suggère que quelq'un ajoute une remarque indiquant "accepted by Core in Jacksonville 2018" dans le dépôt github

Patrice Roy prend ensuite le contrôle du Wiki, Jens Maurer étant appelé chez SG1, et cinq autres dossiers éditoriaux (ou pas, l'un d'entre eux étant plus subtil : préciser le comportement d'un dynamic_cast sur un pointeur nul)

Dîner à l'hôtel cette fois, format buffet. C'était bon, pour être honnête : bar à salade, saumon, zucchinis grillés, etc. J'ai escamoté le dessert car mon corps est un peu saturé de sucreries. Excellente compagnie d'ailleurs, avec les toujours charmants Roger Orr, John McFarlane et Christof Meerwald. J'ai quitté vers 13 h pour corriger un peu. J'ai trois supervisions d'essais en cours, et j'ai réussi à donner une rétroaction à l'un des trois (je vais essayer de faire les deux autres avant la fin de la semaine).

On reprend vers 13 h 35 avec les trucs qui méritaient clarification de matin

[implimits] Unclear text #1794

Jens Maurer explique la raison pour laquelle cet Editorial Issue est porté à notre attention. On parle des limites minimales supportées par une implémentation :

[expr.dynamic.cast] Incorrect wording regarding dynamic_cast #1453

Jens Maurer explique qu'il est clair que le texte normatif existant est brisé, mais on parle de wording de priorité P0. C'est un cas de dynamic_cast sur un pointeur nul. Le code en exemple est :

struct T1 {};
struct T2 {};
T1 * p = nullptr;
T2 * q = dynamic_cast<T2*>(p); 

Roger Orr pense que la procédure traditionnelle est meilleure dans ce cas-ci que comparer les textes avant / après dans github

Mike Miller pense qu'on peut s'en sortir avec un seul otherwise (pour le cas du pointeur nul), mais Jens Maurer indique que certaines clauses demandent un examen particulier

La difficulté dans la section sur dynamic_cast est sur le plan de la terminologie, que certains tests statiques sont enchevêtrés avec des tests dynamiques. La règle pour les pointeurs nuls est http://eel.is/c++draft/expr.dynamic.cast#4 mais elle fonctionne avec des entités non-polymorphiques, ce qui ne sied pas à dynamic_cast

[dcl.array] Padding before/after sequence of array subobjects #568

Jens Maurer explique le contexte dans lequel la demande a été reçue

Roger Orr dit que nous avons suggéré NAD

CWG2345 Jumping across initializers in init-statements and conditions #1949

Jens Maurer : il semble y avoir un défaut trivial de terminologie qui permet d'escamoter des initialisations. C'est Core Issue 2345. Jumping across initializers in init-statements and conditions. Le correctif proposé est simple, et personne ne se trompe ici en pratique, mais le texte normatif est incorrect

Mike Miller n'est pas à l'aise avec le texte proposé, qui lui semble laisser quelques options malpropres ouvertes. Il note aussi que les définitions de conditions dans le texte normatif sont un peu trop éparpillées pour notre confort. Jens Maurer et Mike Miller échangent des idées de formulations à privilégier, et on en arrive à un consensus

Jens Maurer pense que le lieu où le problème a été noté est en fait une déclaration, même si la grammaire ne le dit pas explicitement

[dcl.spec.auto] Use of undeduced placeholder types #1947

Le problème est simple : éviter auto x = x; qui est couvert en soi, mais pas de manière générale (p. ex. : auto x = [x] { return x; }; n'était pas couvert correctement, ou encore auto x = sizeof x;)

Jason Merrill pense que le changement proposé brise le cas qui empêchait précédemment d'écrire ceci :

auto f();
void g() { &f; }  // error, f's return type is unknown

Mike Miller pense qu'on devrait laisser le texte tel qu'il était auparavant, mais ça ne fonctionne pas. On travaille sur une formulation adéquate. Patrice Roy valide qu'elle n'empêche pas l'écriture de λ récursives (et on arriver à éviter cet irritant : une λ récursive doit avoir un type connu a priori – un std::function par exemple) ce qui évite de se retrouver avec un cas où le type est simplement auto)

Patrice Roy voit un truc amusant qu'on vient d'empêcher, mais chut, je me tais parce qu'on ne veut pas que ça sorte de la pièce...

Core Issue 2254: Standard-layout classes and unnamed bit-fields

Aaron Ballman a préparé une formulation

Ben Saks demande si nous devrions clarifier ce qui doit être fait quand le premier cas est un bit-field, mais on convient que le texte donne des garanties qui, si elles ne sont pas respectées, mènent à du code ill-formed

Core Issue 2207: "Alignment of allocation function return value"

Roger Orr a réécrit la terminologie du type de retour des fonctions d'allocation de mémoire pour qu'elle tienne compte des allocations over-aligned que nous supportons désormais

Ceci demande un peu de travail, la question étant subtile. Jason Merrill propose qu'on rapporte une partie de la terminologie de LWG vers CWG dû à son aspect très général. Faudra évidemment leur en parler d'abord

Jens Maurer insiste pour qu'on clarifie les attentes sur les versions de new et de delete surchargées par le code client

On va informer les gens de l'état de la situation, et clarifier la terminologie

Core Issue 2292: simple-template-id is ambiguous between class-name and type-name

Jens Maurer explique que le gros du changement est de changer class-name pour type-name à plusieurs endroits dans la grammaire, et affecte les noms de classes, de types et de templates

Jens Maurer : un class-name est le nom d'une classe ou d'une spécialisation de class template

Jens Maurer : la plupart des autres noms, incluant les template templates, sont des type-name

Jens Maurer : auparavant, un typedef de class-name était un aussi class-name, ce qui dérangeait dans certains appels de destructeurs

Jason Merrill : on a un problème grammatical de type reduce/reduce conflict avec ~ suivi d'un nom de pseudo-destructeur

On s'entend sur une formule. Jens Maurer va la retravailler et nous revenir

Core Issue 2293: Requirements for simple-template-id used as a class-name

Jens Maurer : nous en avons parlé lors d'une téléconférence. Jens Maurer a récupéré le terme valid en tant qu'entité grammaticale, et l'a utilisé à fins utiles pour les template-id

L'exemple montrant des applications de la terminlogie est :

template<class T, T::type n = 0>
class X;
struct S {
  using type = int;
};
using T1 = X<S, int, int>;   // error: too many arguments
using T2 = X<>;              // error: no default argument for first template parameter
using T3 = X<1>;             // error: value "1" does not match type-parameter
using T4 = X<int>;           // error: substitution failure for second template parameter
using T5 = X<S>;             // ok

Jason Merrill suggère d'alléger l'écriture en ramenant tous les cas de validation des template parameters à une même section, mais Jens Maurer explique que l'effet ne serait pas celui souhaité (à cause de l'ordre d'évaluation des clauses, on aurait des comportements inappropriés dans certains cas). On retravaille le tout et on y arrive, une bonne chose

Core Issue 2294: Dependent auto static data members

Jens Maurer explique le raffinement, qui explicite dans quel cas un membre de classe de type auto est d'un type dépendant

Faisal Vali pense que le nouveau cas est couvert par un cas antérieur, mais on découvre que les deux cas examinés sont disjoints

Faisal Vali demande pourquoi on se limite aux variables static; le problème semble aussi s'appliquer aux attributs d'instance. On change static data-member par variable tout simplement

Core Issue 2309: Restrictions on nested statements within constexpr functions

Jens Maurer : ceci a été discuté en téléconférence

Jens Maurer : la reformulation vise à permettre une fonction constexpr qui retourne une λ en empêchant que la λ ne puisse impacter le côté constexpr, au sens où les énoncés de la λ ne font pas partie des énoncés de la fonction la retournant

Dinka Ranns : pourquoi spécifie-t-on l'absences des init-statements?

Jens Maurer : parce qu'ils ne sont pas à propos dans une fonction constexpr

Mike Miller découvre qu'on peut insérer un bloc asm{} dans un init-statement, ce qui donne froid dans le dos en lien avec les λ. John Spicer remarque aussi que try est dans la liste

On va y réfléchir pendant la pause

On prend une pause vers 15 h 30. Pendant la pause, Titus Winters vient solliciter Jens Maurer pour une proposition sur les pointeurs intelligents, et Ville Voutilainen vient solliciter John Spicer poupour une proposition de Herb Sutter visant à modifier les règles d'ADL.

On reprend l'étude terminologique

Core Issue 2312: Structured bindings and mutable

Proposition de résolution par Jens Maurer. L'enjeu est que les Structured Bindings doivent respecter les qualifications const – ou mutable – de ce à quoi elles correspondent, et que le texte existant pouvait appliquer const sur un attribut mutable

Jason Merrill suggère une retouche. Jens Maurer est ouvert dans la mesure où le lvalue-ness est conservé; faut pas oublier que nous avons avec ceci des lvalue qui ne désignent pas des objets à proprement dit

Core Issue 2308. Structured bindings and lambda capture

Jens Maurer dit qu'il y a un mensonge dans l'affirmation de base. §8.4.5.2 p8 indique que si une λ capture une Structured Binding (et quelques autres trucs), le programme est ill-formed

Mike Miller : indiquons NAD. Pour tout changement, allez voir EWG

Core Issue 2321: Conditional operator and cv-qualified class prvalues

L'intention est de mieux supporter le code suivant :

struct A {};
struct B : A {};
using T = const B;
A a = true ? A() : T();         // prvalue case
volatile B b;
volatile A& av = true ? a : b;  // lvalue case

Jens Maurer apporte deux formulations : une plus concise mais un peu plus opaque, et l'autre plus explicite mais beaucoup plus longue. On penche pour la plus compacte, la mécanique utilisée dans l'explication étant décrite ailleurs dans le standard

Core Issue 2322: Substitution failure and lexical order

Dans les mots de Jens Maurer : "It seems instantiation of (class) templates is observable, e.g. by checking on the injection of friend functions defined in-class", ce que la proposition de résolution vise à corriger. L'exemple donné est douloureux (voir h<T>()) :

template <class  T> struct A { using X = typename T::X; };
template <class  T> typename T::X f(typename A<T>::X);
template <class  T> void f(...) { }
template <class  T> auto g(typename A<T>::X) -> typename T::X;
template <class  T> void g(...) { }
template <class  T> typename T::X h(typename A<T>::X);
template <class  T> auto h(typename A<T>::X) -> typename T::X;  // redeclaration
template <class T> void h(...) {}
   void h() {
      f<int>(0);          // OK, substituting return type causes deduction to fail
      g<int>(0);          // error, substituting parameter type instantiates A<int>
      h<int>(0);          // ill-formed, no diagnostic required
   }

C'est ill-formed, NDR car il n'y a pas de candidats

Thomas Köppe fait remarquer, à juste titre, qu'un programme comme ceci serait ill-formed :

struct X {
   template <class T> T f() const;
};
template <class T> auto X::f() const -> T { return {}; } // ne respecte pas la forme initiale

On y va avec ça

Core Issue 2339: Underspecified template arguments in structured bindings

Petit ajustement dont nous avons discuté plus tôt cette semaine, pour clarifier le type de I dans get<I>() tel qu'utilisé pour les Structured Bindings

Jason Merrill fait remarquer que le même i sert aussi dans std::tuple_element

Mike Miller pense qu'il est sage de placer le type de i un peu plus tôt pour que cette information s'applique aux deux cas

On procède

2252. Enumeration list-initialization from the same type

Richard Smith estime que la formulation proposée n'est pas suffisament claire, mais qu'il comprend l'intention et peut terminer de manière éditoriale

Jason Merrill et Richard Smith sont d'accord pour interdire les narrowing conversions

2118. Stateful metaprogramming via friend injection

On revient sur cette technique obscure qu'on souhaiterait voir bannie

Richard Smith pense qu'on voulait en faire un P3 le temps qu'on trouve une manière de procéder. Vendu

2202. When does default argument instantiation occur?

Dans ce qui suit, que vaut b?

#include <type_traits>
template<class T> struct Foo { Foo(T = nullptr) {} };
bool b = std::is_constructible<Foo<int>>::value; // false
int main() {}

Jens Maurer fait remarquer qu'il n'y a pas de fonction template à instancier ici

Richard Smith pense que ce n'est pas l'enjeu; les substitutions ne sont pas faites

Jason Merrill fait remarquer que cela évite de générer des fonctions illégales si elles ne sont pas utilisées

Richard Smith pense que si on a plutôt deux constructeurs, l'un appelant l'autre, l'enjeu serait peut-être différent :

#include <type_traits>
template<class T> struct Foo { Foo() : Foo(nullptr) {}; Foo(T) {} };
bool b = std::is_constructible<Foo<int>>::value; // true
int main() {}

Jason Merrill dit que g++, si une substitution réussit, s'en souvient

Richard Smith est d'avis que si nous permettons SFINAE sur des fonctions avec paramètres par défaut, nous travaillons à l'avantage de nos usagers en acceptant plus de programmes raisonnables

Faisal Vali fait remarquer que le corps des λ échappe à cette règle, une bonne chose

(je prends le Wiki; ce qui suit est parcellaire)

2219. Dynamically-unreachable handlers

Le cas de test est particulièrement méchant :

#include <cstdio>
#include <cstdlib>
void f() {
  struct X {
    ~X() {
      std::puts("unwound");
      std::exit(0);
    }
  } x;
  throw 0;
}
int main(int argc, char**) {
  try {
    f();
  } catch (int) {
    std::puts("caught");
  }
}

Mathias a pire encore. Richard Smith a des frissons :

extern "C" int puts(const char*);
struct ThrowInDtor{
   ~ThrowInDtor() noexcept(false) {
      puts("in dtor");
      throw 1L;
   }
};
int main() {
   try {
      ThrowInDtor throws;
      throw 1;
   } catch (int) {
      // unreachable
   }
}

On continue demain...

Nous avons la réception en l'honneur de Bjarne Stroustrup ce soir. Notre hôtel est près d'une rivière (semble qu'il y ait parfois des dauphins dedans, mais je n'en ai pas vu cette semaine), assez large, et plusieurs ponts la traversent; notre souper est de l'autre côté de la rivière, vis-à-vis l'hôtel, entre le pont qui est à gauche et le pont qui est à droite. Un 20-25 minutes de marche environ. Certains y sont allés en transport en commun, je suis de ceux qui ont préféré marcher.

L'endroit qui nous a accueillis est un restaurant pas vilain, qui fait sa propre bière (de qualité), et nous étions reçus par Bjarne Stroustrup lui-même qui a gagné quelques prix importants cette année, dont un particulièrement prestigieux et qui lui a rapporté un montant d'argent appréciable, et c'est avec une partie de ce montant qu'il a financé cette soirée. Un buffet (c'était bon), la bière et le vin à volonté (mais le bar fermait vers 21 h), un court discours bien senti, et des copies de The Design and Evolution of C++ pour tout le monde (j'ai déjà ce livre, qui est excellent, mais je ferai circuler ma copie).

J'ai eu un bon repas, sympathique, en partie avec Aaron Ballman, Mike Miller, Mark Zeren, James Touton (qui m'a raconté des trucs amusants sur Starcraft, dont il est un des artisans originaux), JF Bastien (qui a réussi un petit miracle aujourd'hui) et plusieurs autres. Je suis parti tôt car j'ai beaucoup de travail à faire, et parce que je devais passer à l'épicerie avant de revenir à l'hôtel (ce qui me faisait environ 50 minutes de marche au total).

Au retour, j'ai travaillé un peu et j'ai réussi à me coucher avant minuit...

Jour 4 16 mars 2018

... et je me suis réveillé à 5 h, mon objectif étant d'appeler ma belle Za pour 6 h car son réveil semble perdre de son efficacité avec le passage du temps, or je me suis rendormi (j'ai rêvé que je nourrissais des chats; mon quotidien normal me rattrape!) et j'ai repris conscience vers 6 h 20, à quel moment j'ai fait l'appel attendu, mais elle était déjà sur pied.

Le temps de prendre ma douche et de retourner quelques messages, le temps était venu d'apporter les bananes à CWG et de se mettre au boulot.

Mike Miller planifie les dates des prochaines téléconférences, de même que les séances de travail suite à la plénière demain (tristement, mon avion étant en milieu d'après-midi, je devrai quitter après la plénière contrairement à mes habitudes)

D0542R4 – Support for contract based programming in C++

Juan Daniel Garcia dit avoir consulté EWG, et tout effet de bord dans un contrat sera considéré comportement indéfini

Jens Maurer revient sur le fait que observable side-effect n'est pas un terme défini en C++. C'est un terme informel, observable existe et side-effect a une définition formelle, masi observable side-effect n'en a pas encore. Ceci rend la frontière entre ce qui se qualifie et ce qui ne se qualifie pas difficile à tracer

Hubert Tong dit que dans les alentours de Placement New, où on dit qu'on peut remplacer un objet qui a une destructeur non-trivial et tomber dans le comportement indéfini, on a du weasel-wording qui ressemble à ce qu'on cherche à avoir ici. On parle de §6.6.3 p5 : "It is implementation-defined whether the dynamic initialization of a non-local inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of that variable. It is implementation-defined in which threads and at which points in the program such deferred dynamic initialization occurs"

Juan Daniel Garcia pense avoir une définition pas si mal : un effet de bord qui peut être observé après évaluation

Aaron Ballman demande si lever une exception d'un contrat est un observable side-effect dû à l'affectation au exception_ptr. Juan Daniel Garcia dit oui

Aaron Ballman demande si cela tient même si le contrat attrape l'exception. Juan Daniel Garcia dit que la question est de savoir s'il est possible d'observer cet effet de l'intérieur de la fonction

Juan Daniel Garcia : la condition no side-effect ne tient que si le contrat est satisfait; s'il n'est pas satisfait, les effets de bord sont acceptables

Jens Maurer : le mot after est beaucoup utilisé, particulièrement after undefined behavior, or au sens du raisonnement sur le code, le concept de « après un comportement indéfini » n'existe pas vraiment

John Lakos : j'aimerais réduire l'élision au test lui-même. Si l'élision se produit dans le corps de la fonction, c'est un bogue. Le fait que les conditions soient séquentielles permet de progresser en accumulant du savoir sur la situation

Nathan Sidwell : on ne peut donc pas optimiser le corps d'une assertion pour optimisation

John Lakos : en fait, on ne veut pas élider le corps de la fonction sur la base d'un effet de bord de la condition

John Lakos : la présence d'un axiome dans le test ne supprime pas l'obligation de faire des tests dans le corps de la fonction

Nathan Sidwell : en mode checking, je peux élider le test déjà validé par le contrat?

John Lakos : oui. Le contrat énonce un fait, et on peut optimiser sur la base de ce fait

Nathan Sidwell : si la précondition déréférence un pointeur de manière où ça exploserait si le pointeur était nul, puis-je considérer pour mon optimisation que le pointeur est non-nul? Même si ce n'est pas une précondition en tant que tel...

John Lakos : les axiomes décrits par le contrat font partie de l'interface de la fonction

John Lakos : c'est le possible effet de bord dans un contrat qui ne devrait pas mener à l'élision de code dans la fonction

Jens Maurer : le texte décrivant la machine abstraite de du langage ne sied pas à cette demande. L'origine du comportement indéfini est inconnue. Il y a une distance entre ce qui est souhaité, et ce que les mots sur lesquels nous travaillons nous donneront

John Lakos : soyons donc conservateurs. Si on passe par l'effet de bord, on a du comportement indéfini et c'est la faute du code ayant introduit l'effet de bord

Hubert Tong : nous avons mentionné le cas du possible déréférencement d'un pointeur nul. Pour le comportement indéfini, c'est un cas qui existe déjà, rien de nouveau. Le comportement indéfini surviendrait si le compilateur, en générant le code, que l'on passera là

John Lakos : on fera avec. Si un contrat déréférence un pointeur nul, nous serons punis

Jens Maurer : ma perception de ceci est des assertions plus raffinées, avec l'état des mots dans le document présentement

John Lakos : j'aurais aimé mieux, justement parce que ce ne sont pas des macros, mais les macros fonctionnent. Cela dit, ceci est meilleur que des macros

Juan Daniel Garcia : je ne pense pas que c'est comme des macros. Je peux maintenant définir des préconditions et des postconditions

Roger Orr : la syntaxe est significativement meilleure aussi

John Lakos : les assertions dans le corps de la fonction ont le même effet sur le code généré, pour une partie des contrats du moins

Juan Daniel Garcia : je comprends donc qu'il n'y a pas de concept d'après un comportement indéfini (le texte exact est "If evaluating the conditional-expression when the contract is satisfied would lead to a side effect that can be observed after that evaluation the behavior is undefined"). L'intention est de montrer que l'observation doit pouvoir être faite de l'intérieur de la fonction assujettie au contrat

Jens Maurer : supposons que le test prenne un mutex mutable dans une fonction const. Est-ce un effet de bord?

John Lakos : oui

Juan Daniel Garcia : si le mutex a été relâché dans le test, peut-on observer la saisie du mutex de la fonction?

John Lakos : je maintiens que c'est un effet de bord. C'est visible d'autres threads

Juan Daniel Garcia : soyons restictifs, considérons tout cela comme des effets de bord, et nous relaxerons les règles quand nous en saurons plus

John Lakos : mais un effet de bord observable change le sens d'un programme!

Roger Orr mentionne une note qui pourrait aider, mais Jens Maurer n'est pas convaincu

John Lakos : il y a une voie de contournement, soit insérer le code ayant des effets de bord dans le corps de la fonction et l'enlever de l'interface

Aaron Ballman : je ne pense pas qu'il soit possible de tester un contrat en situation de concurrence (on échange sur les enjeux)

Jens Maurer : je ne veux pas aller dans une discussion de design, mais bien cerner les contours du concept d'effet de bord observable. J'essaie de m'assurer que le seul effet de bord permis soit essentiellement la modification de variables locales aux fonctions appelées lors des tests

Dinka Ranns demande une précision sur les modes de contrôle, §10.6.11 p14 et p10

Nathan Sidwell : je ne sais pas comment implémenter §10.6.11 p12-13 à travers un pointeur de fonction. On me demande de donner le contexte du point d'appel lors d'une violation de contrat. Dans une fonction noexcept (ou avec les options de compilation comme -fnoexcept), ou dans un contexte de Tail-Call Optimization, je n'ai pas nécessairement la mécanique pour faire du Stack Unwinding et retomber sur mes pattes. À moins que l'appelant de génère un jeton au cas où il y aurait une violation de contrat, ce qui est inefficace

Jens Maurer : il y un checking mode présentement qui est prévu pour des tests très légers (le mode always). Nathan Sidwell est inquiet de ce cas

John Lakos : ça ne peut pas être dans l'interface; ça ne serait pas résolvable, c'est une contradiction. Ne mettons pas ça dans l'interface

Jens Maurer : dans l'interface donc, on doit voir les préconditions et les postconditions, mais pas les assertions?

John Lakos : absolument

Juan Daniel Garcia : si on appelle une fonction sans respecter le contrat, on veut savoir d'où vient le bris de contrat

John Lakos : c'est un problème considérable à résoudre pour les clients. Connaître le contexte d'appel est une des forces des contrats!

Hubert Tong : on a un pointeur de fonction. Le contrat fait partie du type. Ce n'est pas implémentable

John Lakos : c'est un cas limite de pointeur de fonction avec peut-être des contrats

Hubert Tong : un pointeur de fonction est dynamique. Je peux pointer sur une fonction avec contrat ou sur une fonction sans contrat. Techniquement, ça impacte toutes les fonctions en forçant un paramètre supplémentaire

John Spicer : interfacer avec C vient de changer radicalement

John Lakos : on veut permettre aux vendeurs d'offrir un mode mixed-mode build, mais ne pas l'imposer

Aaron Ballman : et si on interface avec la bibliothèque standard du langage C?

Juan Daniel Garcia : je comprends. Faudrait ajouter un paramètre caché...

Nathan Sidwell : peut-on placer un contrat sur une fonction extern "C"?

John Lakos : non

Nathan Sidwell : la fonction appelée ne sait pas si elle est appelée par un pointeur ou pas

John Lakos : c'est au point d'appel qu'il est particulièrement important de constater un problème, pas dans la fonction appelée

John Spicer : c'est le problème résolu par les assertions : quand une fonction échoue, c'est souvent qu'on l'a mal appelée

John Lakos : pour générer un Stack Trace, ça prend un suivi...

John Spicer : on peut demander au système d'exploitation qui nous a appelé, ça peut être utile en général. Imaginons les pointeurs de fonctions, les méthodes virtuelles...

Nathan Sidwell : je pense que c'est impossible de supporter cette partie du dossier

Aaron Ballman : peut-on empêcher de prendre un pointeur de fonction sur une fonction avec contrat, du moins d'ici le moment où on saura comment faire?

Roger Orr : ... et faire la même chose pour les méthodes virtuelles

Exemple :

void f(int x)
  [[expects: x > 0]]
{
}
void (*pf) = f;
int g() {
  pf(2);
  f(2);
}

Mike Miller : ... à moins d'utiliser un foncteur contenant l'état requis

Nathan Sidwell : que faire avec les fonctions passées aux algorithmes standards?

Juan Daniel Garcia : on peut s'en sortir avec des λ

Nathan Sidwell : ma difficulté est de rapporter l'appelant dans un contexte où nous avons des appels indirects

John Spicer : je vois deux problèmes : les contrats, et la difficulté de rapporter le contexte d'appel. Je pense que pour le deuxième élément, on a un problème plus vaste que prévu, et que EWG devrait se pencher sur le problème

Jonathan Caves : on a une proposition en ce sens, justement

Juan Daniel Garcia : pour les pointeurs de fonctions, je vais revenir dans un prochain meeting avec une proposition

Aaron Ballman : considérez std::function et les algorithmes au passage...

Hubert Tong : ... et commencez par EWG, pas CWG, avec cette nouvelle proposition

John Lakos : je suis d'accord avec vous. Cela dit, si je n'ai que des assertions, j'ai besoin d'un Stack Trace

Nathan Sidwell : je pense que c'est aussi le point de John Spicer

Jens Maurer : nous avons aussi le souhait d'expliciter le non-support (ou le support conditionnel) des contrats dans un extern "C", et le cas du always qui ne doit pas (peut-être?) apparaître dans une interface

Juan Daniel Garcia pose une question de terminologie pour les mixed-mode builds

Hubert Tong propose une approche. Jens Maurer note : "It is implementation-defined the condition under which ... (rest of the phrasing except for the last part "or the use of")"

Juan Daniel Garcia et Hubert Tong valident quelques autres précisions terminologiques

Hubert Tong : il y a la question de l'accès, à savoir ce à quoi les contrats ont accès (attributs d'instance?)

Roger Orr : la porte est ouverte pour renommer des paramètres, mais y a-t-il des risques de violations d'ODR?

Dinka Ranns indique quelques occurrences de terminologie antérieure. Juan Daniel Garcia va s'en occuper

Dinka Ranns suggère de clarifier le texte pour les noms introduits dans un contrat afin de représenter la valeur de retour d'une fonction

Hubert Tong : je ne pense pas que les types de retour covariants collaborent bien avec les types de retour décrits dans un contrat, pour raisons d'ODR (l'enjeu est que les contrats sont hérités). Faut clarifier ce qu'on entend

Jason Merrill pense que dans ce cas, on a une non-correspondance du code au contrat

Roger Orr : peut-on se limiter au contrat dans la classe de base tout simplement?

Juan Daniel Garcia : Gabriel Dos Reis est ici. Peut-on réexaminer le cas des pointeurs de fonctions? (Juan Daniel Garcia explique, Mike Miller donne plus de détails)

Nathan Sidwell : une violation de précondition doit rapporter le point d'appel lors de l'échec. Une fonction noexcept n'a pas de handler et une levée d'exception dans ce cas doit appeler std::terminate()

Gabriel Dos Reis : nous avons établi que mixed-mode build ne peut qu'etre conditionnellement supporté, le temps qu'on trouve des idées pour le réussir. L'affirmation de non-implémentabilité me préoccupe : nous pourrions avoir des métadonnées et garder un pointeur sur celles-ci dans le prélude des appels, comme on le fait pour déboguer. J'aimerais séparer les affirmations de non-implémentabilité de la difficulté d'implémentation

Nathan Sidwell : c'est une non-implémentabilité pratique, pas théorique. Il pourrait ne pas y avoir les informations dans le programme pour faire ce qui est demandé

Jason Merrill : demander la disponibilité de l'information au point d'appel est énorme, pour les usagers comme pour les implémenteurs. Nous demander d'essayer est autre chose complètement

John Spicer : nous aimerions une facilité plus générale pour avoir accès au point d'appel, indépendamment des contrats, pour éviter de transporter cette information avec chaque appel

John Lakos : mon équipe pense que la facilité en question serait extrêmement utile

Roger Orr : P0881 est sur la table chez LEWG cette semaine

Pause vers 10 h 17. C'était divertissant tout ça, et fort instructif!

Il semble qu'une des propositions sur la table après la pause, chez EWG, touche la mitigation des problèmes de sécurité découverts avec Spectre et Meltdown. Sais pas si on va vouloir aller jouer là avec C++

Herb Sutter vient nous visiter

P0905R0 – Symmetry for spaceship

L'idée générale est de faire en sorte que si a<=>b est défini, b<=>a le soit aussi

Benjamin Craig demande une clarification sur le recours au symbole @ dans le texte. Jens Maurer explique que c'est um placeholder

Richard Smith fait remarquer que dans les règles, on a un lookup récursif, mais il ne lui semble pas clair qu'il n'y a pas de risque de donner dans une récurrence infinie dû au @ générique (si on précise que <=> n'est pas viable pour @ à cet endroit, ça règle le problème)

Jens Maurer : qu'on dit les autres groupes?

Herb Sutter : EWG a dit oui et LEWG a dit oui. Si CWG passe, restera LWG mais de leur côté, c'est surtout mécanique

Pas grand-chose à ajouter. Si LWG l'accepte, ce sera un Core Motion demain

explicit(bool) – P0892

BR explique comment on pourrait utiliser sa proposition pour réduire considérablement l'effort requis pour rendre un constructeur conditionnellement explicit. En gros, explicit prend (implictement!) le sens explicit(true), mais il est aussi possible d'avoir explicit(false). Évidemment, le booléen est une constante connue à la compilation. C'est une excellente idée!

Richard Smith demande s'il a la permission de faire une changement éditorial. BR accepte

Il y a du travail grammatical à faire pour que l'évaluation de la condition se fasse au bon moment

John Spicer demande quand on devrait évaluer cette condition dans un cas d'un constructeur générique

Richard Smith fait remarquer qu'il faudra spécifier les contextes (p. ex. : value-dependent) où l'overload resolution sera impacté. Par exemple, qu'il faut générer tous les constructeurs, puis évaluer les conditions, puis rejeter les cas non-valides

On se demande si SFINAE devrait être impliqué. Richard Smith suggère qu'on consulte LWG et qu'on procède si ça leur rend service

Proposed wording for likely and unlikely attributes (Revision 5) – D0479R5

L'auteur a clarifié des détails, par exemple d'une même instruction ne peut être à la fois [[likely]] et [[unlikely]]

Richard Smith aimerait un exemple, mais le fera de manière éditoriale

Aaron Ballman demande si les points d'application sont suffisamment clairs. On semble penser que si. John Spicer propose une clarification en ce sens, qui a la qualité d'alléger le texte, et Richard Smith ajoute quelques précisions

On fait plusieurs retouches. C'est une drôle de proposition : un court texte, une longue note non-normative disant de ne pas abuser, et une longue liste de remerciements

2264. Memberwise copying with indeterminate value

On revient sur cet amusant cas :

struct A { int x, y; };
A passthrough(A a) { return a; }
int main(void) {
   A a;
   a.x = 0;
   return passthrough(a).x;
}

Jens Maurer rappelle que le problème est la copie du y non-initialisé, ce qui mène à du comportement indéfini même si y n'est pas utilisé en pratique

Richard Smith dit que ça peut fonctionner ici pour les copies implicitement générées, mais se demande s'il est possible de le faire fonctionner dans le cas d'un constructeur de copie maison

Jens Maurer demande si le constructeur de copie =default fait un std::memcpy(). Semble que... pas pour le moment

Richard Smith demande si y : default serait une introduction intéressante. Peut-être, mais faudrait commencer par proposer quelque chose à EWG

Mike Miller demande ce qu'on fera si on utilise par défaut une Trap Representation pour les entiers non-initialisés

Jens Maurer dit que faudra utiliser std::memcpy() sous la couverture

2306. Nested friend templates of class templates

John Spicer préfère y réfléchir pour le moment

2265. Delayed pack expansion and member redeclarations

On ouvre cette boîte de Pandore :

template<typename ...T> struct Tuple; 
template<class T, class U> struct Outer; 
template<class ...T, class ...U> 
struct Outer<Tuple<T ...>, Tuple<U ...> > { 
  template<class X, class Y> struct Inner; 
  template<class ...Y> struct Inner<Tuple<T, Y> ...> { }; 
  template<class ...Y> struct Inner<Tuple<U, Y> ...> { }; 
}; 
Outer<Tuple<int, void>, Tuple<int, void> > outer; // diagnostic requis?

Jens Maurer fait une surdose de ... et veut aller dîner

Plus sérieusement, Jens Maurer pense que si nous en venons à définir quelque chose de non-dépendant, un diagnostic serait raisonnable

Jason Merrill : si on a un Pack Expansion pour lequel on a toute l'information, on peut l'instancier

Richard Smith : il y a une différence observable entre ne rien substituer et substituer partiellement

Jason Merrill : ill-formed, NDR

Richard Smith s'en occupe

Pause vers 12 h 1. Bref dîner avec la délégation canadienne, où nous avons clarifié notre vision commune des cas susceptibles d'être controversés en plénière (il n'y en a pas vraiment de notre point de vue pour la rencontre en cours; pas qu'il ait manqué d'action ou de controverses cette semaine, évidemment, mais bien que nous ne pensons pas les voir exploser en plénière). Ce fut tout de même intéressant : nous avons un nouveau membre (un spécialiste de systèmes embarqués), et Olivier Giroux, nouveau Chair de SG1, nous a fait un rapport détaillé sur la semaine, et en particulier sur les exécuteurs, qui sont un élément important de certains des principaux progrès attendus pour C++ 20 et (éventuellement) C++ 23.

Nous recommençons avec une proposition intéressante

Class Types in Non-Type Template Parameters – P0732R0

Jeff Snyder nous présente sa proposition. Le plan est d'utiliser des instances de types maisons en tant que non-type template parameters

Une restriction au modèle est l'obligation que <=> soit =default pour que l'équivalence au sens des templates soit respectée

Aaron Ballman demande s'il y a une raison particulière pour mentionner la dimensionnalité des tableaux. Jeff Snyder explique que les tableaux ne sont pas trivialement comparables. Jens Maurer ajoute que la phrase est récursive et que sans cette subtilité, la récursion serait incorrectement formulée

Jens Maurer : les changements dans §17.1 permettent d'utiliser des void* en tant que non-type template parameters. EWG s'en est-il aperçu?

Jeff Snyder : puis-je éviter ces irritant?

Jens Maurer : en spécifiant "other than cv-pointer-to-void"?

Richard Smith : il me semblerait surprenant d'accepter des types arbitraires mais pas void*

Mike Miller : on peut tout accepter sauf void*, et s'attendre à ce que EWG décide rapidement

Richard Smith : la distinction entre type et non-type s'évapore rapidement...

Jens Maurer : si les non-type template parameters sont des constexpr lvalue, je peux prendre leur adresse. Aurai-je la même adresse dans toutes les unités de traduction?

Jeff Snyder : le comportement doit être le même que pour les variables inline constexpr

John Spicer : et si on a un objet d'un type dépendant, quand on aura le template réifié, il se peut qu'on se ramasse avec une nouvelle adresse?

Jeff Snyder : je ne sais pas

Richard Smith : et si on a une variable inline template<auto>...?

Louis Dionne : on partage un objet global plutôt que de le copier

John Spicer : que nous devions avoir les mêmes adresses parfois, et des adresses distinctes d'autres fois me préoccupe

Louis Dionne : j'ai eu des ennuis semblables avec les littéraux textes dans des templates : les partager ou les copier?

Jeff Snyder : la différence est-elle importante?

Richard Smith : il faudrait un mangling externe pour chaque objet. Ça grossira les binaires

Jason Merrill : unspecified?

Richard Smith : non, ça amènerait des violations d'ODR. On peut utiliser les adresses comme clés dans une std::map par exemple...

Jason Merrill : peut-on empêcher une adresse de sortir d'un contexte constexpr?

Jeff Snyder : si ces trucs sont toujours des prvalues, on pourrait avoir deux adresses identiques pour deux objets distincts

 On discute des limites des copies sur ces objets, et des conséquences...

Richard Smith fait remarquer que déjà, dans un template<int N>, prendre deux fois l'adresse de N mène à deux temporaires distinctes

On discute de diverses avenues, mais ça finit par déborder sur des questions évolutionnaires

Jeff Snyder dit que EWG a discuté de ces questions sans statuer

Richard Smith dit que la proposition, dans son état actuel, demande une variable constexpr distincte pour chaque instanciation

Jeff Snyder dit comprendre que EWG s'en remet à CWG ici

Richard Smith propose une variable distincte par valeur, pour les classes

Jason Merrill semble capable de vivre avec ça

Jeff Snyder souligne qu'il faut faire attention avec le code existant, pour éviter un Breaking Change

Richard Smith amène une nouvelle Core Issue sur la précision du terme placeholder type qui s'élargit au fil du temps

(je n'ai pas tout pris en note; ce serait difficile à suivre hors contexte)

Louis Dionne pense que sa proposition sur les littéraux textes dans un template est presque la même chose que la proposition de Jeff Snyder. On discute un peu, et on suggère la fusion de leurs deux propositions. Louis Dionne dit que la proposition de Jeff Snyder est plus générale que la sienne, mais que la sienne couvre un cas que celle de Jeff Snyder ne résout pas

Jason Merrill pense que la solution pour le linkage pour Jeff Snyder pourrait être appliquée à la proposition de Louis Dionne

Richard Smith trouve que c'est un gros morceau, et préfère voir les propositions séparément

Jeff Snyder explique que les deux approches sont peut-être incompatibles, la sienne changeant le sens d'un string literal d'une manière qui empiète sur les plans de Louis Dionne

Louis Dionne rétracte sa proposition

Static reflection – P0194R5

Axel Naumann a fait des changements : on ne référence plus les lieux précis dans le code source; les recours à integral_constant qui n'étaient pas applicables ont été remplacés par quelque chose de plus verbaux mais de plus précis; quelques trucs ont été adaptés pour correspondre aux besoins de LWG

Axel Naumann : plusieurs des demandes sont raisonnables et pertinentes, mais pour le proche futur

Hubert Tong : on ne peut pas techniquement parler de C++ 17 + concepts dans ces documents

Axel Naumann : j'ai des trucs plus pressants à traiter pour le moment, mais je vais m'en occuper

Richard Smith et Jens Maurer voient des ennuis, mais avec le Core Language, pas avec la proposition. C'est un peu apeurant, mais c'est pas la faute d'Axel Naumann

Axel Naumann : si on requiert une opération qui mène à un type concret, on a une erreur

On discute de Reflected Entity. Axel Naumann explique qu'il faut distinguer les types sur lesquels on réflecte et les métaobjets que nous obtenons. Richard Smith dit que la définition de reflection-related peut n'être que d'une utilité limitée. Axel Naumann dit qu'il est disposé à mettre la liste de cas dans une note, mais s'il fait cela, il préfère éliminer le terme grammatical. Richard Smith pense que le mot reflect suffit à lui seul. Jens Maurer met en relief que le terme est utilisé de manière récursive

Axel Naumann : que signifie reflect alors?

Richard Smith : c'est la relation qui associe un métaobjet à un objet

Axel Naumann : c'est une relation qui vous convient?

Richard Smith : et pour ce qui est de l'accès?

Axel Naumann : oui, c'est là que le terme doit être défini, bravo!

Richard Smith : donc, reflection-related est une relation entre objets

Mike Miller : ces changements doivent-ils être faits avant que l'on ne procède en plénière?

Jens Maurer : la question de l'accès est insuffisamment spécifiée selon moi

Mike Miller : LWG a accepté ce document. Si on accepte aussi, ce sera la version initiale de la TS

Hubert Tong n'est pas à l'aise avec une motion de cette envergure le vendredi après-midi

Richard Smith suggère que Hubert Tong en parle avec son NB

Mike Miller dit que c'était prévu à l'origine, et que ça avait circulé

Jens Maurer peut vivre avec ce qui est là; on peut raffiner la terminologie ultérieurement, selon lui, et il ne pense pas qu'il y ait d'irritants insurmontables

Jens Maurer pense que reflection-related peut rester tel quel pour le moment

Hubert Tong : la référence à C++ 17 + concepts lui semble suspecte, mais on peut détourner les yeux

Jens Maurer est d'accord avec Hubert Tong

Axel Naumann est d'accord qu'il y a là un os, les concepts demeurant dans le futur

Richard Smith : la syntaxe des concepts dans ce document est celle de C++ 20, pas celle du TS

Mike Miller : nous ne sommes pas opposés à ce que LWG mette cette proposition de l'avant en plénière demain

Layout-compatibility and Pointer-interconvertibility Traits – P0466R1

Lisa Lippincott a fait des changements, dont ce merveilleux extrait : "Rewriting the abstract and much of the front matter to remove incorrect blather about reinterpret_cast. Instead, I’ve tried to restrict the text to mostly true statements".

Lisa Lippincott propose un nouveau nom pour un trait, qui devient is_pointer_interconvertible_base_of<T>. Elle évite de donner une définition et réfère plutôt à la définition du standard. Ce trait s'adresse à des types T complets

Jens Maurer demande si EWG a vu ceci; Lisa Lippincott dit que nous sommes les premiers

Hubert Tong dit que le recours à reinterpret_cast fait qu'avoir une seule base pointer-interconvertible suffit

Jason Merrill pense que le trait proposé est bien défini

Lisa Lippincott propose ensuite une fonction constexpr bool is_pointer_interconvertible_with_class(T T::*m) noexcept, de même qu'une fonction constexpr bool is_corresponding_member(R0 T0::*m0, R1 T1::m1 noexcept)

Jason Merrill demande si l'intention est que, si T0 et T1 ne sont pas standard-layout ceci soit faux. Lisa Lippincott dit oui

Jens Maurer demande le retrait du bonheur du papier (il y a des "it happily fails" à quelques endroits). Richard Smith dit qu'il va obtempérer

Lisa Lippincott demande si elle doit revenir devant CWG si elle n'a pas de changements sémantiques. On lui dit que non

La pause débute tardivement car nous voulions compléter le travail avec Lisa Lippincott d'abord; il n'y a plus de biscuits quand j'arrive, mais heureusement, CWG garde une réserve de bananes (mais on a droit à des biscuits d'urgence en fin de pause)

char8_t: A type for UTF-8 characters and strings (Revision 1) – P0482R1

Tom Honermann nous fait une présentation avec diapos et tout. On ne voit pas ça souvent à CWG

Mike Miller donne des conseils de formatage pour respecter les règles en vigueur

Jens Maurer remarque que tout code utilisant u8'c' ou u8"abc" sera brisé. Tom Honermann dit que chez Google, on a environ 200 cas, donc c'est rien. Il s'attend à ce que les système d'exploitation aient besoin d'une mise à jour

Tom Honermann dit que le design se base sur sa vision du langage considérant la présence (mais faible utilisation) de char8_t depuis C++ 11

Jens Maurer suggère de simplifier la liste de types T pour lesquels sizeof(T)==1 par une formule plus directe, car cette liste s'allonge (char, unsigned char, signed char, std::byte, std::char8_t, std::int8_t, std::uint8_t, bool, j'en oublie peut-être)

PR : impact sur la compatibilité avec C?

Tom Honermann : oui, comme avec std::char16_t et std::char32_t d'ailleurs

Jens Maurer : comptes-tu en parler avec les membres de WG14?

Tom Honermann : je ne comptais pas le faire, mais faudrait voir

Jens Maurer : faudrait au moins ajouter le nécessaire à l'annexe sur la compatibilité avec C

Jens Maurer : est-ce que LWG a vu ceci?

Tom Honermann : non, et ça ne sera pas cette semaine

Daveed Vandevoorde : mais EWG l'a vu n'est-ce pas?

Tom Honermann : oui

Daveed Vandevoorde : le fait qu'un char8_t soit non-signé est mis en relief à plusieurs endroits, mais ça laisse parfois entendre que ça ait un sens particulier. On pourrait sans doute être moins insistants à certains endroits

Jens Maurer : un can est devenu un shall, mais c'est inconfortable. Le mot can est une capacité, alors que shall est une obligation placée sur le code client

Jason Merrill : je reviendrais à can

John Spicer : je suis sceptique quant à notre capacité de réaliser ce projet sans conversions...

Tom Honermann : c'est pas trivial

Jens Maurer : la compatibilité avec C semble avoir été traitée, finalement. Je l'ai trouvée

On discute des pièges et des enjeux de l'utilisation d'Unicode dans les systèmes d'exploitation contemporains. Des heures / jours / mois / années de plaisir

Standard containers and constexpr – P0784R1

Dinka Ranns présente brièvement le document

Jens Maurer : est-ce que CWG a déjà vu ceci?

Daveed Vandevoorde : non, mais LEWG l'a vu

Daveed Vandevoorde : nous avons un plan pour, éventuellement, permettre à la mémoire allouée de manière constexpr de vivre une promotion et de devenir de la mémoire statique

Mike Miller : on a donc maintenant des destructeurs triviaux à l'exécution mais constexpr à la compilation?

Jens Maurer : si le destructeur constexpr ne libère pas la mémoire, qui le fera? Jens Maurer et Daveed Vandevoorde discutent pour expliciter la mécanique. Daveed Vandevoorde explique un peu de la magie qui se cache dans la terminologie. Daveed Vandevoorde explique aussi qu'avoir ou pas un destructeur constexpr est une propriété des objets, pas des types

Jens Maurer fait remarquer que la terminologie proposée ne tient pas compte d'horreurs comme la levée d'exceptions dans un destructeur constexpr

On fait diverses retouches

Roger Orr signale que constant destruction est initialement une définition, qu'il faut mettre en relief

Mike Miller souligne que le fait que le destructeur ne puisse pas être virtuel n'est pas capturé par le texte proposé

On fait beaucoup de changements. Jens Maurer demande pourquoi on met en relief le caractère statique de l'espace d'entreposage ou de la durée d'entreposage

Dinka Ranns : parce qu'on a eu un commentaire indiquant que si le destructeur est constexpr et si la mémoire est statique, on pourrait éviter de l'appeler

Daveed Vandevoorde : dans un destructeur constexpr, on peut avoir des delete, mais des new aussi. Un new constexpr n'appelle pas operator new

Mike Miller : quelle est la profondeur d'appels que l'on peut réaliser dans un constexpr new?

(j'ai pris le Wiki vers 17 h 15; c'est super intéressant, mais ça ne passera pas en plénière demain, à moins d'une surprise)

Jens Maurer : la destruction de données statiques n'est pas un contexte constexpr

Daveed Vandevoorde : ça pourrait être fait dans un destructeur constexpr quand même

Jens Maurer : pourquoi s'en préoccupe-t-on?

Daveed Vandevoorde : imaginons une variable constexpr. Traditionnellement, elle ne pouvait pas avoir de destructeur. Maintenant, elle peut, et ceci pourrait servir dans une variable locale d'une fonction appelée dans un contexte constexpr

On ferme à 17 h 30. Mike Miller remercie les participantes et les participants.

Je passe à ma chambre grignoter un peu, puis je redescends pour la séance de soirée, première rencontre du nouveau groupe d'études que nous avons formé : SG15, Tooling, dirigé par Titus Winters de Google. On cherche à mieux accompagner nos usagers et à régler le (vieux et douloureux) problème d'obtenir des bibliothèques autres que la bibliothèque standard.

Je ne posterai pas de détails, bêtement parce que j'étais le scribe de la soirée (j'ai tout, mais c'est pas nécessairement publiable). Les grandes lignes :

Une séance de deux heures, bien remplie

De retour à ma chambre, je parle un peu à mon amoureuse, que je retrouverai demain soir (enfin!), et je vais faire dodo.

Jour 5 17 mars 2018

Bonne St-Patrick!

Debout vers 5 h, douche, rasage, préparatifs de dernière minute pour le trajet (au son de la musique d'un spectacle de Brel, merci Youtube : https://www.youtube.com/watch?v=unj3oS9VZLk&feature=share)). Je remplis le questionnaire électronique de mon agent de voyage (merci à mon agente et amie Annie Bélanger pour avoir simplifié ma vie au maximum!)

Je fais mon check-out, je viens m'installer une heure d'avance dans la salle où la plénière se tiendra et il y a déjà plusieurs personnes au travail. Je m'installe et je prépare mon document de prise de notes pour être le plus efficace possible.

La mécanique est la suivante :

Je peux donc, ce matin, prendre les Motions en ligne et préparer le document de manière telle qu'il ne me reste qu'à transcrire ce qui est dit et, le cas échéant, le résultat des votes

À l'arrivée de Herb Sutter, je valide les droits de vote. Nous avons neuf pays présents cette semaine, mais sept d'entre eux sont des NB au sens du vote (la France n'a pas de représentant officiel cette semaine, mais elle a des membres votants; la Pologne a pour sa part des délégués, mais n'est présente qu'en tant qu'observateur, ce qui changera vraisemblablement à Rapperswil). Je vous rappelle que dans les groupes de travail et dans les groupes d'études, toutes les expertes et tous les experts peuvent voter, mais en plénière, le droit de vote appartient aux membres de l'annuaire ISO (on parle de délégués de certaines entreprises, un vote par entreprise dans ce cas, et de délégués officiels de certains pays, un vote par délégué dans ce cas; pour le Canada, je suis l'un de ces délégués), et les pays qui ont un poids en tant que NB ont aussi des responsabilités et un engagement financier.

Je ne peux pas relater la plénière en détail, car j'étais occupé à jouer mon rôle de secrétaire pour la rencontre, mais les grandes lignes sont :

Je suis parti tout de suite après, mon vol quittant Jacksonville au milieu de l'après-midi et midi étant derrière nous

J'ai eu le plaisir de partager mon trajet en taxi avec Billy Baker et Howard Hinnant, puis j'ai bavardé avec Billy Baker (qui transite par Charlotte comme moi et sur le même avion, mais en direction de Tulsa alors que je retourne chez moi à Montréal) en attendant notre carosse volant...


Valid XHTML 1.0 Transitional

CSS Valide !