À propos de WG21, Issaquah 2023 (février)

Nous avons tenu pour la première fois depuis Prague en 2020 une rencontre en personne du WG21 pour la période allant du 6 au 11 février 2023. Cette rencontre était aussi accessible à distance, ce qui m'a permis de participer presque à temps complet (merci à mes employeurs, le Collège Lionel-Groulx et l'Université de Sherbrooke, de m'avoir accomodé encore une fois).

Les principaux thèmes de la rencontre étaient la résolution de NB Comments pour C++ 23, quelques nouveaux mécanismes pour C++ 26 et des travaux importants sur les plans de la sécurité (SG23) et des contrats (SG21).

Tout ce qui suit est anonymisé et simplifié, dans le respect du code de conduite d'ISO en vigueur lors de nos rencontres.

Ce document est incomplet (j'ai manqué de temps). Je compléterai dès que possible.

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

Jour 0 6 février 2023

C'est ma première participation à distance (n'ayant pas pu participer à Kona en 2022) alors j'ai un peu de préparation à faire. Pour les gens qui participent à distance, la rencontre se tient en partie par Zoom et en partie par d'autres canaux, incluant un système de clavardage nommé Mattermost que j'ai dû installer et configurer. Les gens qui ont participé à distance jusqu'ici se sont dit ravis du support technologique et de la fluidité des travaux, alors je m'attends à ce que tout se passe relativement bien.

Il y a trois heures de décalage horaire entre Montréal et Issaquah, ce qui me permet de démarrer les enfants le matin (faire les lunchs et tout le tralala) mais me transformera en fantôme à la maison en fin d'après-midi et tard en soirée...

Quelques irritants mineurs de démarrage (le lien pour la plénière sur le Wiki de la rencontre était incorrect, mais les échanges par Mattermost ont permis de régler le tout rapidement). John Spicer explique les règles de fonctionnement, le code de conduite, etc. Nous avons 19 NB participants cette semaine. Comme c'est la coutume, les nouvelles participantes et les nouveaux participants sur présentent (il y en a 25!). Nous chercherons à terminer le traitement des NB Comments sur C++ 23 cette semaine (le document de travail est https://wg21.link/n4928).

L'hôtel est un peu petit pour nous alors il nous faut utiliser certaines plages de soirée pour des réunions de SG. Nous essaierons d'éviter les prises de décision durant ces séances tardives car les soirées servent traditionnellement à des discussions plus informelles en vue du futur.

---

Pour aujourd'hui, je compte passer l'essentiel de mon temps avec CWG, qui me manque beaucoup. Demain, je devrai passer une partie de mon temps à LEWG pour y présenter un enjeu technique sur un nouveau conteneur (std::hive, autrefois std::colony) conçu par mon ami Matthew Bentley (c'est un dossier sur lequel on travaille depuis presque dix ans!).

Quelques NB Comments pour C++ 23

On y va.

US 7-035 6.5.2 [class.member.lookup] Inconsistent use of T and C

On convient que c'est un dossier clos (le Wording proposé fonctionne)

GB-031 5.2 [lex.phases] Clarification of wording on new-line and whitespace P2348

Il se peut qu'on ait une mise à jour de cette proposition; sinon, ce sera un rejet faute de consensus pour le changement (on s'attend à plusieurs itérations s'il y a une proposition).

FR-021-013 5.3p5.2 [lex.charset] Codepoint names in identifiers

Devrait être corrigé par p2736 (que nous verrons plus tard aujourd'hui)

FR-020-014 5.3 [lex.charset] Replace "translation character set" by "Unicode" P2749

SG16 recommande de rejeter ceci. Ce sera aussi notre position.

FR-010-133 [Bibliography] Unify references to Unicode

Il y a une proposition à ce sujet.

Quelques Tentatively Ready Issues et quelques Ready Issues

Voyons voir si nous pouvons faire quelques ajustements en vue de C++ 23.

Core Issue 2659 – Missing feature-test macro for lifetime extension in range-for loop

Ça semble banal (mettre à jour la valeur de cette macro)

Core Issue 2662 – Example for member access control vs. overload resolution

Semble prêt

Core Issue 2667 – Named module imports do not import macros

Semble prêt

Core Issue 1789 – Array reference vs array decay in overload resolution

Ceci est actuellement ambigu, et on propose d'ajuster les règles pour préférer 1 :

template <class T, size_t N> void foo(T (&)[N]); // 1
template <class T> void foo(T *t);               // 2
// ...
int arr[3]{1, 2, 3};
foo(arr);

Hubert Tong  : il se peut que ce soit un DR sur C++ 23, et je ne vois pas d'information quant aux divergences d'implémentation en ce moment.

Jason Merill note que c'est actuellement ambigu alors ça ne brisera pas de code existant

Résolution : Ready (DR sur C++ 23) (voir plus bas, il y a eu des changements depuis)

Core Issue 2475 – Object declarations of type cv void

C++ ne permet pas d'objets de type void, mais C permet des déclarations extern de type void. Notre intention est de rendre ces déclarations illégales en C++ :

int f(), x;            // OK, function declaration for f and object declaration for x
extern void g(),       // OK, function declaration for g
  y;                   // error: void is not an object type

PR : pourquoi C supporte-t-il ceci?

Aaron Ballman  : pas clair (le traitement des qualifications cv est parfois quelque peu confus en C)

Shafik Yaghmour propose https://godbolt.org/z/h5zKf98sd qui montre qu'il n'y a pas de divergence d'implémentation (tous les compilateurs le rejettent).

Résolution : Ready (DR sur C++ 23)

On fait des ajustements éditoriaux mineurs

Core Issue 2483 – Language linkage of static member functions

Il y a divergence dans le traitement des fonctions membres static et non-static :

extern "C" {
   struct A {
      static void f();
      constexpr static void (*p)()=f; // error: must point to a function whose type has C language linkage
   };
}

L'ajustement proposé rend CWG heureux

Résolution : Ready (DR sur C++ 23)

Core Issue 2517 – Useless restriction on use of parameter in constraint-expression

On a un exemple et du texte pour interdire ceci :

template<typename T> concept C = requires (T a) {
   requires sizeof(a) == 4; // OK
   requires a == 0; // error: evaluation of a constraint variable
};

... mais c'est inutile car a n'est pas utilisable dans un contexte constexpr. On peut supprimer le texte redondant

Résolution : Ready (DR sur C++ 23)

Core Issue 2519 – Object representation of a bit-field

L'objet de celle-ci est le texte qui discute de la représentation en mémoire des objets, qui semble incorrectement décrire les champs de bits. Un peu de travail semble requis pour que les mots utilisés soient les bons, alors on y reviendra plus tard cette semaine

Core Issue 2523 – Undefined behavior via omitted destructor call in constant expressions

Il semble qu'un destructeur dans un contexte constexpr qui ne soit pas appelé soit techniquement du comportement indéfini :

#include <memory>

constexpr int test_basic_life_p5() {
   class guard_t {
      int &ref_;
   public:
      explicit constexpr guard_t(int &i) : ref_{i} {}
      constexpr ~guard_t() { ref_ = 42; }
   };

   int result = 0;

   auto alloc = std::allocator<guard_t>{};
   auto pguard = alloc.allocate(1);
   std::construct_at(pguard, result);
   // std::destroy_at(pguard);
   alloc.deallocate(pguard, 1);

   return result;  // value depends on destructor execution
}

int main() {
   constexpr auto v = test_basic_life_p5();
   return v;
}

La proposition semble correcte.

Résolution : Ready (DR sur C++ 23)

Core Issue 2525 – Incorrect definition of implicit conversion sequence

C'est subtil, mais les mots existants rendent ceci ambigu plutôt que de mener à f(B) :

struct A{
   A(int) = delete;
};
struct B{
    B(int) {}
};
void fun(A); // #1
void fun(B); // #2
int main() {
   fun(0);    // #3
}

On doit réfléchir un peu à celle-ci

Core Issue 2529 – Constant destruction of constexpr references

On parle d'une amélioration à la terminologie.

Résolution : Ready (DR sur C++ 23)

Core Issue 2530 – Multiple definitions of enumerators

Quelle horreur : le texte actuel permet (par omission) d'écrire :

enum E { e, e };

On corrige ça.

Résolution : Ready (DR sur C++ 23)

Core Issue 2537 – Overbroad grammar for parameter-declaration

On semble trop permissifs quant aux qualifications de paramètres (la production grammaticale acceptée semble trop large; elle accepte static, extern et d'autres étrangetés). Cette proposition suggère de prendre une production similaire mais moins vaste

Plusieurs semblent surpris de ce qui est permis... Hubert Tong note que la proposition d'ajustement est probablement trop vaste elle aussi. Jens Maurer se demande si les restrictions sémantiques ne couvrent pas déjà nos arrières. Davis Herring note qu'on a une contrainte indirecte qui parle de la possibilité d'initialiser l'objet. Christof Meerwaald note que auto n'est pas correctement couvert par le texte

On n'est clairement pas prêts à accepter ceci. Peut-être plus tard cette semaine

Core Issue 2539 – Three-way comparison requiring strong ordering for floating-point types

La terminologie actuelle accepte ceci :

struct MyType {
   int i;
   double d;
   std::strong_ordering operator<=>(const MyType &c) const = default;
};

... mais ça ne fait pas de sens car double n'est pas strongly ordered.

Jason Merill se demande si le problème vient de la définition du mot usable. Davis Herring précise que le code est usable, mais que l'échec vient plus tard quand le type de retour est pris en considération

La proposition de RS est de rendre ceci équivalent à une fonction =delete. PR : Would the fact that =default means `deleted` in this case be something that occurs in some other «usable» contexts too or do we foresee it to be limited to spaceship? Jason Merill et Davis Herring discutent du sens de usable qui semble omettre le type de retour

La proposition suggère de considérer static_cast<R>(a<=>b) pour évaluer le volet usable.

Jason Merill investigue les mots utilisés pour les expressions requires

Davis Herring jongle avec Well-Formed when treated as an unevaluated operand (tiré des mots de LWG)

On retravaille et on en reparle peut-être plus tard cette semaine

Core Issue 2558 – Uninitialized subobjects as a result of an immediate invocation

Ceci est interdit, mais peut être permis dans des contextes clos (les mots actuels ne donnent pas cet effet) :

struct A {
   int n;
   consteval A() {}
};
constexpr A a; // implementations reject

Résolution : Ready (DR sur C++ 20)

(pause de dîner à Issaquah; on reprend dans une heure)

Au retour de la pause, Corentin Jabot n'est pas immédiatement disponible pour présenter p2736 alors nous poursuivons.

Core Issue 1789 – Array reference vs array decay in overload resolution (revisité)

Jason Merill signale l'avoir implémenté sur l'heure du dîner et avoir constaté un bris de certains de ces tests, en particulier certains T& (le Core Issue semblait viser spécifiquement une référence sur un tableau, mais le texte accepte des références dans un sens trop large). Les cas de paramètres T& (ou pire : const T&) sont extrêmement fréquents alors il faut faire attention. On cherche une formule...

On revient sur la décision, il faut encore travailler un peu. Pas Ready pour le moment, mais bien Open, priorité 2 (on sait ce qu'on veut, on ne sait pas comment le dire).

Core Issue 2602 – consteval defaulted functions

Il n'est pas clair si une fonction =default qui est consteval est aussi une fonction constexpr correcte :

template <typename Ty>
   struct A {
      Ty n;
      consteval A() {}
   };
template <typename Ty>
   struct B {
      Ty n;
      consteval B() = default;
   };
A<int> a;
B<int> b;

Dans les deux cas, a et b, le code devrait refuser de compiler car n n'est pas initialisée, mais il y a divergence entre les implémentations...

La terminologie proposée ajoute le terme constexpr-suitable et le définit. On se demande si on vise C++ 23 ou C++ 26. Roger Orr suggère de le résoudre tout de suite dû aux divergences d'implémentation (on vérifie et les divergences semblent disparues depuis le signalement initial), Hubert Tong signale que la divergence existe encore sur les raisons du rejet. Shafik Yaghmour constate que gcc accepte: https://godbolt.org/z/cK6vh8rPG

Résolution : Ready (DR sur C++ 23)

Core Issue 2674 – Prohibit explicit object parameters for constructors

Ceci recoupe Deducing this et corrige un bogue de spécification

Résolution : Ready (pas un DR, mais destiné à C++ 23)

Core Issue 2682 – Templated function vs. function template

Le texte existant était parfois confus sur le sens précis de ces termes. L'ajustement définit clairement templated function, templated class et templated variable

Résolution : Ready (DR sur C++ 23)

Core Issue 2687 – Calling an explicit object member function via an address-of-overload-set

Ceci semble aussi un petit correctif de bogue terminologique, qui clarifie l'intention dans le cas des fonctions membres

Résolution : Ready (pas un DR, mais destiné à C++ 23)

Core Issue 2690 – Semantics of defaulted move assignment operator for unions

Simple mais efficace, une clarification

Résolution : Ready (DR sur C++ 23)

Core Issue 2691 – hexadecimal-escape-sequence is too greedy

La proposition améliore le texte, mais impacte la grammaire alors on la regarde de plus près

Résolution : Ready (pas un DR, mais destiné à C++ 23)

Core Issue 2519 – Object representation of a bit-field (revisité)

Mike Miller a retravaillé le texte de celle-ci. Bon travail

Résolution : Tentatively Ready (on va viser C++ 26 au cas où on aurait échappé quelque chose de subtil étant donné la portée de la définition)

Quelques cas de Drafting

En attendant Corentin Jabot, on examine des cas de Drafting qui ont été soumis depuis la dernière rencontre

Core Issue 1353 – Array and variant members and deleted special member functions

Certaines définitions clés omettaient de mentionner quand certaines fonctions spéciales des union / std::variant et des tableaux étaient définies ou supprimées. Jason Merill a proposé quelque chose d'intéressant mais de difficile à analyser. Après un certain temps, on décide de le retravailler un peu

Core Issue 2485 – Bit-fields in integral promotions

Celle-ci porte sur les promotions arithmétiques et le traitement insuffisant des champs de bits, mais l'auteur n'est pas disponible pour en parler avec nous. On va traiter le dossier plus tard

Issues with Review Status

On continue...

Core Issue 1396 – Deferred instantiation and checking of non-static data member initializers

Le texte dit « Non-static data member initializers get the same late parsing as member functions and default arguments, but are they also instantiated as needed like them? And when is their validity checked? ». Celle-ci a été discutée sommairement en novembre, mais date de... 2011. Il semblerait que c'est résolu en partie par Core Issue 2631 qui décrit les règles d'évaluation des valeurs des paramètres par défaut (ceci devient subtil quand on a consteval et std::source_location).

On le considérera clos en soi, et on gardera les enjeux associés aux classes imbriquées dans le contexte de Core Issue 1890.

Core Issue 2543 – constinit and optimized dynamic initialization

Celle-ci a été discutée chez EWG. On a des règles qui empêchent l'initialisation dynamique de constinit, mais aussi d'autres qui permettent au compilateur de réaliser une initialisation dynamique comme une initialisation statique dans certains contextes. La proposition est une interdiction de faire magiquement fonctionner constinit (ce qui réduit les probabilités de divergences d'implémentation). On a des choix terminologiques inhabituels ici (on parle dans l'hypothétique, « ... même si l'implémentation devait réaliser l'optimisation... »)

On va la laisser sur le brûleur quelques jours et en reparler.

Core Issue 2485 – Bit-fields in integral promotions (revisité)

Celle-ci porte sur les promotions arithmétiques et le traitement insuffisant des champs de bits. Brian Bi discute de l'intérêt de rapprocher C et C++ dans ce cas-ci. Il explique la procédure appliquée en pratique par gcc, plus proche de C++ que de C. Jens Maurer rappelle que CWG est souvent sur les frontières du langage et tend à aller là où les compilateurs ne vont pas encore. L'enjeu est de savoir dans quel type un champ de bit est promu lors d'une promotion arithmétique (il y a des coins obscurs...). Brian Bi précise que les problèmes sont plus importants si le type du champ de bits est plus grand que int, et nous rappelle qu'il existe des champs de bits sur des énumérations : https://godbolt.org/z/h1ErzoWe6

(petite pause de 15 h 15 à 15 h 30 heure d'Issaquah; l'horaire est très rigide durant ces rencontres, sinon c'est impossible à gérer)

Chose amusante : dans le cas des promotions des champs de bits sur des énumérations, le type sous-jacent est considéré, mais seulement une fois que toutes les autres options ont été essayées.

Brian Bi suggère qu'un DR soit soumis à C. Jens Maurer recommande de passer par SG22, notre liaison officielle avec ce langage.

Core Issue 2658 – Trivial copying of unions in core constant expressions

Un classique : copier un union est un std::memcpy() ce qui implique copier des bits indéterminés s'il y a du padding, ce qui est interdit dans un contexte constexpr. La proposition suggère de le permettre si l'objet source de l'initialisation n'a pas de sous-objets de valeur indéterminée.

Hubert Tong demande si constexpr implique d'offrir un espace d'entreposage. Pas clair que ce soit la clé.

Jason Merill suggère un ajustement terminologique pour clarifier l'intention. Jens Maurer va retravailler le texte et nous revenir.

Core issue 2673 – User-declared spaceship vs. built-in operators

On a plusieurs options (écrites à la main, générées par défaut, réécrites dû à operator<=>()) et dans certains cas ça cause des surprises (l'exemple qui suit n'est pas le seul relevé dans le signalement) :

#include <compare>

enum class E : int {
   Lo = 0,
   Hi = 1
};

constexpr auto operator<=>(E lhs, E rhs) -> std::strong_ordering {
   return (int)rhs <=> (int)lhs;
}

// everybody agrees this is true
static_assert((E::Lo <=> E::Hi) == std::strong_ordering::greater);

// gcc rejects this, msvc and clang accept
static_assert(E::Lo > E::Hi);  // #1

L'enjeu est de bien indiquer les fonctions candidates considérées (ici, la réécriture de operator>(E,E) à partir de operator<=>(E,E) ne découle pas du texte).

On y reviendra cette semaine

Core Issue 2681 – Deducing member array type from string literal

L'enjeu est que ceci ne compile pas actuellement :

template <typename T, std::size_t N>
struct A {
   T array[N];
};
A a = { "meow" };

... car le littéral "meow" (un const T(&)[N]) ne tombe pas dans les cases couvertes par le texte. La proposition sur la table semble convenir... Tentatively Ready pour le moment

Core Issue 1360 – constexpr defaulted default constructors

C'est un enjeu de variable membre initialisée par défaut qui nuisait à la qualité de constexpr en 2011, mais Hubert Tong signale que constexpr est tellement puissant aujourd'hui que c'est devenu NAD. On vérifie et on y revient.

Core Issue 1973 – Which parameter-declaration-clause in a lambda-expression?

La description de cette clause est insuffisamment précise dans le texte actuel (il peut y avoir des parameter-declaration-clause vides ou pas à plusieurs endroits). On travaille plusieurs versions du texte pour en arriver à quelque chose de pas mal. Tentatively Ready pour le moment

Core Issue 2072 – Default argument instantiation for member functions of templates

Le texte ne semble pas couvrir clairement les paramètres par défaut des fonctions templates. L'ajustement (un mot!) est accepté. Tentatively Ready pour le moment

Core Issue 2516 – Locus of enum-specifier or opaque-enum-declaration

Ceci ne compile pas dû au moment où l'énumération est considérée comme ayant été spécifiée (l'ajustement proposé est grammatical) :

template<typename T> struct S { typedef char I; };
   enum E: S<E>::I { e };   // Implementations say E is undeclared in S<E>

Tentatively Ready pour le moment

Core Issue 2520 – Template signature and default template arguments

Cette production grammaticale est beaucoup trop vaste pour la zone où elle est utilisée (elle inclut entre autres les paramètres par défaut du template). Il faut la contraindre. La proposition est d'ajouter des exclusions; la question est de savoir si c'est la bonne approche, et si on a exclut tous les cas qui devaient l'être.

On discute et on n'est pas satisfaits de ce qui est sur la table pour le moment. Encore un peu de travail...

Referencing the Unicode Standard – p2736

Le premier dossier autre qu'un traitement de NB Comment au menu est celui de la conformité de C++ dans la manière dont nous référons au standard d'Unicode, et en particulier celui de la conformité entre ISO 10646 et Unicode. Un peu de rodage pour l'audio en début de séance, mais ça se règle rapidement (respect pour l'équipe technique!). La proposition, en gros, est de référer au standard Unicode plutôt qu'à ISO 10646, ce qui est inhabituel pour un standard ISO.

(j'ai manqué quelques minutes, mais à mon retour un examine les ajouts, les suppressions et les suggestions « novatrices » de cette proposition). Une proposition surprenante est de référencer systématiquement https://www.unicode.org/versions/latest/ un peu comme si nous étions toujours « magiquement » à jour

Hubert Tong signale que nous ne sommes pas en mesure de nous tenir à jour avec UAX#31 en pratique. Il signale aussi que nous n'avons plus la correspondance traditionnelle entre deux représentations de caractères que le texte existant avait, mais que le nouveau texte proposé semble ne pas en tenir compte. Il propose un ajustement :

« The "decoded to produce a sequence of [ ... ] scalar values that constitutes the sequence of elements of the translation character set" wording no longer works as-is because it is the wording equivalent of reinterpret_cast<const TranslationCharacters*>(ScalarValues). Suggestion: "decoded to produce a sequence of Unicode scalar values. A sequence of translation character set elements is then formed by mapping each Unicode scalar value to the corresponding translation character set element." »

...qui tient entre autres compte du fait que les caractères Unicode sont clairement des entiers mais ne sont pas clairement des caractères.

On travaille ensuite le texte pour qu'il soit grammaticalement bien formé et qu'il gagne en clarté. CWG prend soin de la langue...

On ferme vers 17 h 30 heure d'Issaquah (20 h 30 heure de Montréal). Il y a une séance de soirée sur les Ranges à 19 h (22 h ici), je vais essayer d'y participer si je suis encore assez éveillé pour cela (note de dernière minute : Inbal Levi nous a informé que SG9 a eu le temps de traiter toutes les propositions sur la table aujourd'hui et que la séance de soirée est annulée).

Jour 1 7 février 2023

J'ai un empêchement ce matin, alors j'ai manqué les premières 30 minutes de rencontre du comité, mais je me suis joint à CWG dès midi (heure de Montréal; 9 h heure d'Issaquah). À mon arrivée, on travaillait sur Core Issue 2658.

Core Issue 2658 – Trivial copying of unions in core constant expressions

Hubert Tong propose une formulation qui fait en sorte que dans un contexte constexpr, la copie (ou le mouvement) d'un union copie (ou déplace) le membre actif seulement (s'il y en a un).

Tentatively Ready pour le moment

Core Issue 2681 – Deducing member array type from string literal

Christof Meerwaald a essayé la terminologie que nous envisagions avec son compilateur et... ça ne fait pas ce qu'on veut. L'enjeu est un cas de CTAD avec conversions de const char(&)[N] vers unsigned char[N], sans spécifier N. On jongle avec l'idée de rendre l'exemple incorrect (ajuster le commentaire pour indiquer que le code proposé ne compile pas). Ce qui est embêtant est que le code fonctionne sans CTAD... C'est ce qu'on décide de faire en fin de compte (rendre la correspondance d'une référence sur un char[N] à une référence à un unsigned char[N] illégale lors de la déduction).

C'est un sujet assez profond, qui demande réflexion.

Core Issue 2678 – std::source_location::current is unimplementable

On discute ensuite d'un dossier qui recoupe EWG, soit le cas d'une utilisation de std::source_location() dans certains contextes comme une valeur par défaut de paramètre dans une fonction inline et consteval ou encore :

#include <source_location>
inline char *f() {
   static char array[std::source_location::current().line()];
   return array;
}

... Ça crée le chaos, et personne ne sait quoi faire avec ça. Jason Merill va porter la lecture de CWG devant EWG.

Core Issue 2521 – User-defined literals and reserved identifiers

Oh boy, on a un problème pervers :

double operator""_Bq(long double);  // OK: does not use the reserved identifier _Bq (5.10)
double operator"" _Bq(long double); // ill-formed, no diagnostic required:
                                    // uses the reserved identifier _Bq (5.10)

... car le nom _Bq qui débute par _ suivi d'une majuscule est techniquement un nom réservé par [lex.name] (c'est l'espace qui pose problème). On se demande quel serait le bon chemin pour résoudre ceci (ça impacte l'analyse lexicale!), mais on oblige le préfixe _ pour les noms suffixes de littéraux maison! Il faudra interdire formellement l'espace a cet endroit (triste...). Hubert Tong et Aaron Ballman suggèrent de retourner le dossier à EWG car la résolution ne permet pas aux implémentations de réaliser des extensions, ce qui est important dans certains cas. En attendant, on ajuste l'exemple qui contient des espaces en n'en laissant qu'un seul (explictant que c'est désormais déprécié).

Pour fins d'extensions, on explore l'idée de réserver les littéraux dont les noms de suffixes débutent par __ (deux soulignements). Ça impacterait [usrlit.suffix].

(brève pause de 15 minutes)

Core Issue 2663 – Example for member redeclarations with using-declarations

Shafik Yaghmour suggère qu'on ajoute quelques exemples dans cette section pour clarifier les changements importants au processus de Name Resolution apportés par Davis Herring ces dernières années (Shafik Yaghmour rapporte des cas de divergences parmi les implémentations). Un des enjeux est qu'une déclaration using est bel et bien une déclaration, pas une définition, et peut donc être répétée à loisir (ce qu'il faut éviter, c'est de donner deux sens différents à un même nom).

Il se trouve qu'on a un exemple incorrect dans le standard selon l'intention de Davis Herring , et que deux paragraphes se contredisent pour le cas où une classe D a deux parents A et B qui ont tous deux un parent nommé C qui a lui-même un membre nommé i et où D fait using A::i; et using B::i; (ce qui est incorrect, mais c'est pas clair dans le texte du standard).

On examine [namespace.udecl#10] en profondeur. C'est un sujet extrêmement complexe, et Davis Herring essaie de raisonner à travers le tout, mais il se peut qu'on ait à y revenir. Davis Herring pense que [class.member.lookup] montre ce que l'algorithme est supposé faire. On gratte... le problème semble remonter à C++ 98. On a droit à des perles telles que « ce compilateur fait ce qu'on voulait, sauf qu'on n'est pas certains que ce soit ce qu'on veut ».

On finit par en arriver à un exemple simplifié

Tentatively Ready pour le moment (après plus d'une heure trente de réflexion profonde)

Core Issue 2485 – Bit-fields in integral promotions (revisité)

BB propose une nouvelle version de la résolution proposée. Ça semble bien reçu.

Tentatively Ready pour le moment

Core Issue 2531 – Static data members redeclared as constexpr

Ce programme C++ 14 était légal mais est brisé par C++ 17 :

// x.hh
struct X {
   static const int x;
};

// TU 1
#include "x.hh"
constexpr int X::x{};

// TU 2
#include "x.hh"
int main() { return !&X::x; }

Davis Herring pense que ça devrait être légal, donc que le inline implicite ne s'applique pas ici. La résolution convient.

Tentatively Ready pour le moment

(pause de dîner à Issaquah; je fais une brève sieste car j'ai le cerveau en surchauffe)

Referencing the Unicode Standard – p2736

On revient sur ce document, qui a changé depuis hier. Les changements demandés semblent être présents, et on regarde les menus détails de format comme les marqueurs de fin de note quand il y en a.

Fixing std::start_lifetime_as and std::start_lifetime_as_array – p2679

Jens Maurer explique le chemin qu'a suivi cette proposition (importante à mes yeux), et explique aussi pourquoi il est pertinent de la revisiter aujourd'hui (certains ajustements terminologiques ont eu lieu depuis l'examen précédent de la proposition). On fait quelques vérifications sémantiques, mais ça semble solide.

Unevaluated strings – p2351

Une intéressante ici : dans le passage à Unicode, particulièrement UTF-8, que faire des littéraux non-évalués dans static_assert(message), [[deprecated(message)]], _Pragma(), asm, littéraux maison, etc.? La proposition vise à restreindre ces littéraux à l'encodage de la machine.

Truc intéressant : les métacaractères non-standards étaient permis auparavant mais ne le seront plus avec ce changement (certains sont étonnés de cette décision qui semble venir de EWG). L'exemple qui vient en tête serait un programme qui souhaite que les messages d'erreur deviennent colorés en rouge; on nous rapporte que EWG a spécifiquement demandé de ne pas supporter ces extensions. On discute... Dans le cas des _Pragma, les restrictions risquent de briser les choix faits par certains compilateurs. On remarque que le processus de destringizing appliqué par _Pragma peut mener à des chaînes malformées (on note que _Pragma et #pragma ont un comportement différent quant aux métacaractères d'échappement non-standards).

On remarque que [cpp.line] qui définit le texte qui peut suivre #line est suspect, mais les conséquences d'un changement ici sont difficiles à mesurer alors on traitera le dossier séparément à travers une Core Issue (cela touche WG14 aussi, entre autres raisons). Si c'est un bogue, il a près de 50 ans... Ça fait peur!

Après un examen plus approfondi, le caractère implementation-defined de _Pragma nous fait suggérer de ne pas le contraindre (ça impacterait la compatibilité avec C en particulier), du moins pour le moment (aussi, le toucher sans toucher #pragma est préoccupant). Il faudra l'examiner avec un Core Issue cependant. L'auteur explique que ce qui est le plus important est d'éviter du texte avec des préfixes. Hubert Tong suggère d'envoyer un NB Comment à C aussi, et nous apprend qu'il semble probable que la prochaine version de C soit non pas C23 mais bien C24 (trop de NB Comments à traiter).

Un petit bogue dans les ajustements aux littéraux maison permettrait de mettre du texte entre les guillemets dans operator"" ce qu'il faudra corriger (mais c'est trivial à arranger).

(je dois quitter pour LEWG, et pour aller porter mon plus jeune, Ludo, à son cours de karaté)

À mon arrivée à LEWG, on discute de sparse_array et de structures de données qui utilisent le disque plutôt que la mémoire vive. Je révise ma présentation pendant la pause qui précède ma prestation.

(je ne peux pas prendre de notes pendant que je présente p2596)

RETOUR SUR LA PRÉSENTATION

En soirée (22 h 30 heure de Montréal), la séance de SG6 débute. On a cinq propositions sur la table

P2681 – More Basic Statistics

C'est une proposition R1, la R0 proposait des trucs comme la moyenne et l'écart type. Celle-ci ajoute des trucs comme le mode. On discute de qualités d'algorithmes, de préconditions, etc. Le nommage est un enjeu (certaines fonctions exigent des intrants triés, et les noms cherchent à refléter cette exigence), et les signatures de fonctions sont compliquées dans l'abstrait (mais simples à utiliser). Les algorithmes sont optimisés en fonction des types d'itérateurs, et sont paramétrés par des types d'accumulateurs. Certains soulignent que les nouveaux types arithmétiques pourront impacter cette proposition

Le discours est au conditionnel, cependant. Àprès vérification, le présentateur confirme qu'il cherche une rétroaction préliminaire de haut niveau quant aux directions poursuivies. Après une heure de présentation (!), on discute sur la direction générale à prendre (en évitant les – nombreuses! – considérations de qualité d'interface, SG6 n'étant pas la bonne audience pour cela).

P2075 – Philox as an extension of the C++ RNG engines

On parle d'un nouveau générateur de nombres pseudoaléatoires... mais je dois arrêter (trop fatigué)

P1383 – More constexpr for <cmath> and <complex>

Manqué, même si ça m'intéressait (trop fatigué)

P2746 – Deprecate and Replace Fenv Rounding Modes

Manqué, même si ça m'intéressait (trop fatigué)

P2159 – A Big Decimal Type

Manqué, même si ça m'intéressait (trop fatigué)

Jour 2 8 février 2023

Une question de santé avec un des enfants m'a fait arriver tout juste avant que CWG ne débute ses travaux. Je pensais être en retard (je suis manifestement très mauvais pour calculer les délais de décalage horaire; je me trompe sans arrêt). J'ai manqué quelques trucs importants durant mon passage à LEWG hier, en particulier les constexpr Structured Bindings (92686) mais je comprends en lisant le Wiki de Core que l'auteur reviendra plus tard cette semaine.

On a quelques irritants techniques avec le son (on entend bien les gens dans la salle mais ils ne nous entendent pas). On finit par régler le problème (la télévision là-bas était sur « mute » même si on pouvait changer le niveau du volume!)

On revient sur les NB Comments résiduels. GB-031 ne progressera pas (l'auteur prospectif n'aura pas le temps cette semaine).

US8-036 – https://github.com/cplusplus/nbballot/issues/480 couvert par D2788R0: Modular constants

Davis Herring propose une correction aux règles pour les modules important une partition dans laquelle se trouve une constante. Les const sont soumises aux règles du Internal Linkage habituellement et ne se retrouvent pas exportées... ce qui est évidemment problématique! Imaginez : on importe une fonction template qui utilise une constante; la fonction est bien formée dans le module d'origine, mais ne trouve plus la constante lorsqu'elle est instanciée...

La proposition est bonne pour l'essentiel, et nous reviendra après quelques retouches

Core Issue 2678 – std::source_location::current is unimplementable

Jason Merill propose une formulation. L'approche choisie est de faire en sorte que :

« In each such definition, corresponding manifestly-constant-evaluated expressions that are not value-dependent shall have the same value ([expr.const], [temp.dep.constexpr]). »

... ce qui est une direction raisonnable. Joshua Berne pense avoir un exemple de code qui serait brisé par cette résolution (voir https://godbolt.org/z/9bGP8W7Gb) :

// adapted from https://stackoverflow.com/q/61301746/481267
inline auto & g() {
   static int a[
      ([] {
         int i = 0;
         auto l1 = [](int &j) { return ++j; };
         auto l2 = [](int &j) { return j*=2; };
         return l1(i) + l2(i);
      }())
   ];
   return a;
}

.... notez que l'IIFE détermine une taille de tableau et est donc dans un contexte constexpr. Notez aussi que l'expression l1(i)+l2(i) ne définit pas de manière portable un ordre d'évaluation de sous-expressions. C'est très laid.

Le terme « manifestly-constant-evaluated » doit s'écrire « manifestly constant-evaluated » en conformité avec le reste du standard (oui, on retourne l'auteur à l'écriture pour un trait d'union; c'est la nature de la bête). On débat ensuite pour s'assurer que « manifestly constant-evaluated » est le bon outil pour résoudre ce dilemme. On semble d'accord sur le fait que la résolution est suffisamment générale pour régler un bogue introduit avec consteval.

Tentatively Ready pour le moment

Core Issue 1890 – Member type depending on definition of member function

Ceci semble permis par le texte...

struct A {
   struct B {
      auto foo() { return 0; }
   };
   decltype(B().foo()) x;
};

... mais ceci aussi, ce qui est plus agaçant (comment savoir à ce stade si Bar::Baz::Baz() existe, surtout si on place static_assert() plus haut?) :

#include <type_traits>

struct Bar {
   struct Baz {
      int a = 0;
   };
   static_assert(std::is_default_constructible_v<Baz>);
};

Davis Herring pense que l'enjeu général est la dépendance entre les membres. Jens Maurer rapporte que CWG souhaite retarder l'instanciation des classes pour favoriser le support de ces cas d'utilisation. Entre autres, sans cet ajustement, on ne sait pas comment traiter ceci :

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

... ou cela :

template <int> struct X {};
template <class T> struct partition_indices {
   static auto compute_right () { return X<I>(); }
   static constexpr auto right = compute_right;
   static constexpr int I = sizeof(T);
};
auto foo () -> partition_indices<int>;
void f() {
   foo();
};

... et on ne veut pas briser ceci :

 template <class T> struct A {
   static constexpr int num() { return 42; }
   int ar[num()];
};
A<int> a;

Core Issue 2685 – Aggregate CTAD, string, and brace elision

On revisite cette question à nouveau avec une nouvelle proposition terminologique. Il se peut qu'elle ratisse encore un peu trop large. Ce qu'on veut établir ici est une élision d'accolades comme on le fait régulièrement dans les agrégats, mais sans transformer la règle en trou noir. Une des considérations est de savoir si les mots choisis couvrent correctement les tableaux multidimensionnels.

Core Issue 2528 – Three-way comparison and the usual arithmetic conversions

Ceci ne fonctionne pas, car la conversion implicite de ui en i est une Narrowing Conversion ce qui brise les règles de operator<=>() :

void f(unsigned char i, unsigned ui) {
   i <=> ui;
}

Roger Orr propose un ajustement aux règles. On en discute un peu mais ce n'est pas prêt pour adoption encore

(brève pause de 15 minutes; je reviens et on discute des annotations dans le contexte de Core Issue 2538 – Can standard attributes be syntactically ignored?)

Davis Herring explique que EWG souhaite en quelque sorte que nous, CWG, tranchions sur le caractère ignorable ou pas des annotations. On en rediscutera cet après-midi (on a un plus grand nombre de participants ce matin que ce qu'on pense avoir cet après-midi, alors que les discussions sur les contrats draineront une partie de l'équipe, donc on compte essayer de régler les urgences de C++ 23 en priorité)

Core Issue 2664 – Deduction failure in CTAD for alias templates

On a divergence d'implémentation avec un truc comme :

template <class S1, class S2> struct C {
   C(...);
};

template<class T1> C(T1) -> C<T1, T1>;
template<class T1, class T2> C(T1, T2) -> C<T1 *, T2>;

template<class V1, class V2> using A = C<V1, V2>;

C c1 { "" };
A a1 { "" };
C c2 { "", 1 };
A a2 { "", 1 };

... car les règles ne disent pas clairement si l'alias A possède les règles de déduction de C. On réfléchit aux diverses pistes qui nous sont offertes

Core Issue 2521 – User-defined literals and reserved identifiers

Après la suggestion de EWG de réserver tous les identifiants contenant __ peu importe où, on réexamine la question. Jens Maurer nous informe que Cfront utilise __ dans sa génération de code, ce qui explique cette suggestion!

Core Issue 2693 – Escape sequences for the string-literal of #line

Jens Maurer a clarifié cette Core Issue pour faciliter les discussions, en particulier pour ce qui touche à la compatibilité entre C et C++.

Core Issue 2694 – string-literals of the _Pragma operator

Jens Maurer a clarifié cette Core Issue pour faciliter les discussions, en particulier pour ce qui touche à la compatibilité entre C et C++.

Core Issue 2518 – Conformance requirements and #error/#warning

On est informés que EWG souhaite traiter static_assert() de manière semblable. L'enjeu est qu'un programme qui n'est pas IFNDR et ne compile pas doit offrir au moins un message d'erreur, mais la relation de cette règle avec #error et #warning n'est pas claire (doit-on générer au moins un message? Un message par occurence?). Que faire avec #warning ou #error dans une fonction générique qui ne serait pas instanciée? On mentionne aussi qu'il y a un risque de IFNDR pendant l'exécution du préprocesseur...

Un des enjeux importants ici est d'écrire un texte qui fonctionnera même si les changements à static_assert() discutés cette semaine sont acceptés (ce qui permettrait à un template non instancié et contenant un static_assert(false) de ne pas briser le programme). Au passage, Hubert Tong fait clarifier l'idée de « rejeter » un programme ou de « ne pas accepter » un programme (qu'est-ce que ça signifie exactement?), ce qui peut (éventuellement) influencer les actions posées par des compilateurs JIT.

Après une bonne heure de travail, on a (je pense) quelque chose de satisfaisant

(pause de dîner à Issaquah; je promène Pauline le chien et je fais une brève sieste)

P2558 – Add @, $, and ` to the basic character set

L'idée de celle-ci est de rejoindre C qui a fait la même chose récemment. L'auteur signale que par le passé, il existait des ensembles de caractères qui n'incluaient pas ces caractères, mais ce n'est plus le cas aujourd'hui ce qui rend pertinent le fait de les rendre disponibles (ou du moins, qui enlève un obstacle à leur utilisation).

Ce n'est pas un petit dossier : cela affecte la grammaire, l'analyse lexicale (incluant le préprocesseur), les conversions selon les divers encodages possibles, etc. Certains exemples du passé qui étaient malformés deviennent bien formés, et l'inverse est aussi vrai (certaines dénominations alternatives avec des caractères d'échappement sont interdites quand on réfère à un élément du basic character set)

P2537 – Relax va_start Requirements to Match C

C a relaxé les règles pour va_start et n'oblige plus une interaction avec le paramètre précédant ... pour naviguer la va_list, alors cette proposition est de rayer plusieurs passages du standard qui ne sont plus nécessaires. Ceci découle de l'avènement de __VA_OPT__ en C++ que C a aussi intégré, et qui permet des macros variadiques vides. Cela affecte principalement <cstdarg>.

On fait remarquer que C++ acceptait void f(...); mais C ne l'acceptait pas (en C++, c'est un truc qu'on utilise pour des manoeuvres de programmation générique, mais on ne peut pas utiliser les paramètres).

On examine ensuite les conséquences de C++ de ce mécanisme, par exemple s'il est enchevêtré avec des instantiations de templates (entre autres, en C++, les contextes non-évalués peuvent mener à des instanciations de templates). On note aussi que cette proposition, qui demande de se baser sur C23 (ou C24), ne pourra pas être adoptée cette semaine pour une raison de chronologie, mais ce n'est pas dramatique (ça vise C++ 26). Hubert Tong signale que certains passages ne sont pas implémentables pour le moment; l'auteur s'assurera que C ajuste les mots pour faciliter la transposabilité aux deux langages.

On le reverra en temps et lieu (peut-être pas cette semaine dû à l'aller-retour entre WG14 et WG21)

P1967 – #embed - a scannable, tooling-friendly binary resource inclusion mechanism

C'est une proposition R10 alors elle a beaucoup de maturité, et C a accepté l'équivalent. On épluche la grammaire (c'est intéressant, car c'est un mécanisme un peu novateur du préprocesseur). On a __has_embed(fichier) qui prend une valeur parmi 0, 1 et 2 alors je fais remarquer que ce n'est pas un prédicat malgré son nom, mais Jens Maurer signale que 1 et 2 sont tous deux vrais (l'un est « existe et est non-vide », l'autre est « existe mais vide ». C'est donc un prédicat de C!

(je m'absente 15 minutes pour faire le souper des enfants; je reviens et on est encore sur la grammaire)

Jens Maurer suggère d'épurer certaines répétitions de définitions entre la grammaire et l'explication de certaines facettes sémantiques qui y sont associées. On examine les cas où la ressource à consommer n'a pas une taille de byte qui correspond à CHAR_BIT. On remarque une différence entre les deux langages dans la manière d'exprimer le caractère signé ou non de char (les règles normatives ne sont pas les mêmes).

Il semble y avoir une ambiguïté sur l'utilisation du terme « implementation-defined embed parameter » qui peut être interprété comme une option ou comme une obligation. L'aspect du endianness est discuté (ça peut faire une différence sur une machine où CHAR_BIT==16 par exemple, mais quel est le sens du endianness de #embed alors?). On a un exemple montrant ce qu'une implémentation conforme devrait faire; je propose une manière alternative, et ça semble bien reçu.

(pause de 15 minutes; on travaille fort, ça fait près de deux heures et on n'a pas fini tout à fait)

L'interaction entre #embed et les expansions des macros est ensuite examinée (c'est truffé de pièges!). On a travaillé à peu près trois heures sur celui-là, qui va clairement nous revenir.

P2014 – Proposed resolution for US061+US063 - aligned allocation of coroutine frames

Les mécanismes d'allocation pour les coroutines en C++ 20 ne tiennent pas compte d'enjeux de suralignement. Ce que la proposition apporte est une algorithme de décision pour allouer à l'aide du mécanisme le plus approprié. Le texte demande beaucoup de travail (il répète des sections existantes du standard en partie, et semble tenter de de pallier des bogues d'implémentation alors que le Core Text est un enjeu de spécification). On passe beaucoup de temps sur ce texte (90 minutes environ) mais ce n'est pas prêt pour Core. Peut-être plus tard cette semaine...

P2621 – UB? In My Lexer?

Les correctifs demandés ont été faits. Tentatively Ready.

P1854 – Making non-encodable string literals ill-formed

Les correctifs demandés ont été faits. Tentatively Ready.

P2361 – Unevaluated strings

Les correctifs demandés ont été faits. Tentatively Ready.

(assez pour aujourd'hui; je ne ferai pas la séance de soirée pour des raisons familiales)

Jour 3 9 février 2023

On commence la journée avec le toujours pertinent et sympathique Gor Nishanov.

Core Issue 2563 – Initialization of coroutine result object

L'enjeu est la sous-spécification du moment où promise_type.get_return_object() est effectivement appelé. On nous présente dans le détail les réponses aux questions soulevées par cette Core Issue, c'est très pédagogique. Ce n'est pas un enjeu qui doit être réglé cette semaine (ça ne découle pas d'un NB Comment), mais on veut clarifier l'intention et réduire les risques de divergences entre implémentations. Pour en arriver à un exemple qui exige la situation problématique (on crée le return_object, on fait des trucs ensuite, on le retourne, et quelque chose peut arriver entre-temps), ça prend des situations non-triviales (mais réelles). On passe une bonne trentaine de minutes à éclaircir le propos et Jason Merill finit par décider de se risquer à l'écriture d'une résolution.

P1061 – Structured Bindings can introduce a Pack

Celui-là est vraiment très intéressant car il simplifie la manière d'utiliser des tuple et des packs. C'est du gros travail cependant. Au passage, je constate que dans :

auto foo() -> int(&)[2];
auto [...a] = foo();          // a is a structured binding pack containing 2 elements
auto [b, c, ...d] = foo();    // d is a structured binding pack containing 0 elements
auto [e, f, g, ...h] = foo(); // error: too many identifiers

... un truc comme [b,c,...d] est un identifiant alors que b, c et ...d sont des Structured Bindings. Il y a un enjeu dans le message d'erreur qui entraîne une confusion, ce que je fais corriger.

On expérimente un peu. Par exemple, ceci :

auto [...elems] = Emp{};

template <auto> struct VSink {};
struct A {
   A() : VSink<elems>()... {}
};

... semble légal : https://godbolt.org/z/1n96c44dz

Ceci semble demander réflexion (il n'y a rien de dépendant) :

struct C {
   int i;
   long l;
};

template<typename T>
struct D {
  template<int J>
   static int f(int);
};

template<>
struct D<long> {
   static int f;
};

auto [ ... v ] = C{ 1, 0 };
auto x = ( ... + (D<decltype(v)>::f<1>(2)) );

... et quelques ajouts terminologiques (peut-être l'idée de dependent-expression). C'est le plaisir de CWG : ces exemples sont écrits « live »! Jens Maurer fait remarquer que sizeof... de cette nouvelle bestiole est dependent (probablement value-dependent), mais on vérifie et ce l'était déjà. Ce qui est nouveau est que ça peut être non-dependant si on l'applique sur un Structured Binding Pack qui n'est pas value-dependent. Trouver les ramifications de ces changements dans une spécification d'approximativement 2000 pages est... délicat. Il faut entre autres changer quelques occurrences de instantiated pour expanded du fait que les Packs variadiques peuvent maintenant intervenir dans un contexte non-générique.

On travaille sur le raffinement de quelques exemples, puis on prend une pause de 15 minutes. Je reviens et le groupe a commencé (je promenais Pauline le chien)

Des exemples s'ajoutent, incluant :

struct C
{
  int i;
  long l;
};
void f(int, long); // #1
auto [ ... v ] = C{ 1, 0 };
void f(decltype(v)... x) // #2 redeclares #1
{ }

... qui cause un crash de compilateur (notez les types des membres de C qui sont distincts), voir https://godbolt.org/z/9PxYd3nKn, et :

struct Point3 { int x, y, z; };
auto [...elems] = Point3{};
void h(int (* ...)[sizeof(elems)]);
void g(int (*q)[4]) {
  h(q, q, q);
}

... qui ne cause pas de crash mais est similaire : https://godbolt.org/z/oojebsshs. Notez que l'équivalent générique compile : https://godbolt.org/z/3vPo95so6

struct Point3 { int x, y, z; };
auto [...elems] = Point3{};
template <typename T>
   void f(T (* ...)[sizeof(elems)]);
void g(int (*q)[4]) {
  f(q, q, q);
}

On fait de gros efforts pour ne pas enchevêtrer ces nouvelles idées avec le code de templates, sinon ça va exploser partout dans le texte du standard. On en vient à un stade où on constate avoir introduit des fonctions variadiques dans un contexte non-générique, une surprise! Je me permet de signaler que si on permet ceci :

struct C { int i, j; };
auto [...v] = C { 2, 3 };
void f(decltype(v)... p) { }

... les gens vont se demander pourquoi on ne permet pas simplement :

void f(int ... p) {}

... qui en découle logiquement. Je pense qu'on ne pourra pas l'éviter, mais il faudra une proposition distincte.

Hubert Tong ajoute un exemple où TU1 et TU2 dénotent deux unités de traduction distinctes, et où il importe que les signatures de f() soient distinctes pour éviter une violation d'ODR :

#if TU1
struct P2 { int x, y; };
namespace {
   auto [...elems] = P2{};
}
template <typename T> void f(int (* ...x)[sizeof(T() + elems)]) {}
void g() { f<int>(0, 0); }
#else
struct P3 { int x, y, z; };
namespace {
   auto [...elems] = P3{};
}
template <typename T> void f(int (* ...x)[sizeof(T() + elems)]) {}
void h() { f<int>(0, 0, 0); }
#endif

Hubert Tong suggère qu'on doive peut-être expliciter que les elems ici aient un internal linkage. On ajoute la feature test macro manquante et... voilà, presque deux heures de travail profond.

Core Issue 2528 – Three-way comparison and the usual arithmetic conversions

Une nouvelle version de la résolution nous est proposée. Il reste encore des cas à couvrir, par exemple celui où deux types non signés mais de même rang sont comparés (lequel choisir?), ce qui arrive car ce qui suit est possible :

static_assert(!std::is_same_v<unsigned long long, uint64_t>);
static_assert(sizeof(unsigned long long) == sizeof(uint64_t));

Pour le reste par contre, cette résolution résout le problème qu'elle cherche à régler. On harmonisera éventuellement les formulations de cette nouvelle résolution et celles associées aux conversions arithmétiques habituelles. On découvre à la fin que le problème du rang ne surviendra pas avec l'algorithme de décision. On suggère de vérifier que C fait la même chose que nous pour éviter de pervers écarts de comportement... (certains semblent penser que les valeurs pourraient différer à la fin du processus). (note : après vérification, C et C++ semblent conformes dans la procédure, sinon dans les mots)

(pause de dîner à Issaquah; je manque les premières 35 minutes au retour dû à une urgence familiale)

Avant mon retour, CWG a eu le temps de regarder P2788 – Linkage for modular constants et regarde maintenant P2664 – Deduction failure in CTAD for alias templates (ces dossiers demandent l'apport de Davis Herring qui est arrivé entre-temps); pour ce dernier, qui répond à un NB Comment, la solution sur la table est... déplaisante. Le travail se poursuit... On s'entend qu'il faudra faire au moins deux passes dans la résolution alors il faut un premier jet d'ici demain.

[dcl.attr.grammar] Add note about the semantic ignorability of standard attributes #6076

Une résolution a été proposée pour cet enjeu. La procédure fut inhabituelle, le changement était estimé « éditorial » par EWG, mais il y a du Core Wording et l'auteur de la résolution a besoin d'un regard... informé. Le texte initial est pas mal (j'ai conservé la notation TEX) :

\begin{note}
The \grammarterm{attribute}s specified in \ref{dcl.attr} have optional semantics: given a well-formed program, removing all instances of a particular such \grammarterm{attribute} results in a program whose observable behavior is a conforming realization of the original program.
\end{note}

... on travaille un peu la formule (p.ex. : un programme n'a pas de comportement observable, mais son exécution en a un), on ajoute des références à la machine abstraite de C++ en essayant de conserver une conformité entre les sections, mais l'essence demeure. C'est extrêmement subtil de définir deux exécutions équivalentes d'un même programme étant donné des intrants équivalents, cela dit (on se bat avec ça pour plus d'une heure; c'est facile à exprimer informellement, mais avec rigueur, c'est complètement différent). La procédure est inhabituelle dans ce cas, alors je suis curieux de voir comment le vote se fera samedi matin.

Le cas de [[no_unique_address]] revient à quelques reprises (d'abord par moi, puis par d'autres), mais les mots choisis à la fin couvrent même cet étrange cas (après tout, cette annotation ne promet pas de rendre les objets plus petits!)

Core Issue 2518 – Conformance requirements and #error/#warning

Le texte a été retravaillé un peu, mais il reste du travail à faire pour bien porter l'intention. Hubert Tong remarque que ce texte implique un changement sémantique dans la manière dont les fichiers sources sont traités par un compilateur, mais il y a des désaccords sur sa lecture de la situation. On doit réexaminer ce que signifie le terme preprocessing translation unit et voir les conséquences de cette relecture sur le texte. Ça resserre le texte (on définit formellement des termes qui n'étaient qu'informels par le passé), mais on entre dans un conflit avec la définition des modules (la compilation de C++ se fait en sept phases, et on introduit actuellement une sorte de « phase  »)

Tentatively Ready

(pause folle de 17 minutes, assez pour re-promener Pauline le chien!)

Core Issue 2521 – User-defined literals and reserved identifiers

On examine la demande de EWG, adoptée par LEWG, soit réserver __ dans un identifiant pour les implémentations. Je me permets ce commentaire :

« It's just a hunch, but I'm under the impression that removing the right to use a space after operator"" will be seen as imposing a space between > and > in templates was in the past. I understand the problem, but that one's going to come back to us... »

... ce à quoi on convient que ce boomerang va revenir à EWG avant de revenir à CWG, ce qui n'est pas faux. Anyway, on n'y peut rien, c'est pas notre responsabilité de juger de ce choix en effet.

Tentatively Ready

Core Issue 2685 – Aggregate CTAD, string, and brace elision

La nouvelle version de la résolution évite les pièges d'exiger des décisions prises sur la base d'informations qui peuvent ne pas être connues au moment approprié. On la retravaille encore un peu...

Tentatively Ready

Core Issue 2588 – friend declarations and module linkage

On nous informe que EWG en est arrivé à une décision, mais il nous manque des joueurs pour en discuter. On y reviendra.

Core Issue 754 – Lambda expressions in default arguments of block-scope function declarations

Ceci semble résolu par Core Issue 2158.

Core Issue 2476 – placeholder-type-specifiers and function declarators

Ceci fut discuté dans une téléconférence mais aura besoin de réexamen ici (il nous manque un joueur pour ce faire)

Core Issue 2520 – Template signature and default template arguments

La résolution proposée semble convenir. Je note que le terme « signature » exclut le nom et les valeurs des paramètres par défaut (même pour un template).

Core Issue 2526 – Relational comparison of void* pointers

On pense que NAD serait approprié. Il y a divergence entre les implémentations, mais le texte semble convenable. Il semble que la confusion dans ce dossier remonte à C++ 14 avec un texte malheureux. Hubert Tong signale que C définit un ordre entre deux void* (C++ ne fait pas cela, heureusement selon moi), mais il se peut qu'on s'aligne sur C malgré tout pour réduire les incompatibilités entre les deux langages. Ce sera fait à travers un autre Core Issue, et ça passera par EWG.

Core Issue 2417 – Explicit instantiation and exception specifications

La question posée est à savoir si ceci :

template<class T>struct Y {
    typedef typename T::value_type blah;  // #1
    void swap(Y<T>&);
  };
  template<class T>
  void swap(Y<T>& Left, Y<T>& Right) noexcept(noexcept(Left.swap(Right))) { }

  template <class T> struct Z {
    void swap(Z<T>&);
  };
  template<class T>
  void swap(Z<T>& Left, Z<T>& Right) noexcept(noexcept(Left.swap(Right))) { }

  Z<int> x00, y00;
  constexpr bool b00 = noexcept(x00.swap(y00));
  template void swap(Z<int>&, Z<int>&) noexcept(b00);  // #2

... avec instanciation explicite de ceci :

swap<int>(Z<int>&, Z<int>&)

... instancie au point #2 ceci :

swap<int>(Y<int>&, Y<int>&)

... menant à une erreur. On n'a pas de solution pour le moment.

Core Issue 2478 – Properties of explicit specializations of implicitly-instantiated class templates

On remarque certains problèmes avec ce texte en lien avec les changements apportés par P1061 ce matin, alors on ajuste.

Core Issue 2489 – Storage provided by array of char

Nos mots à propos du début de la vie des objets ou de l'espace attribué pour des objets sont ambigus. Il faut resserrer le discours. On retire char de la liste de trucs qui créent des objets plutôt que de l'espace pour des objets.

Tentatively Ready, mais ça risque de nous revenir.

Core Issue 2504 – Inheriting constructors from virtual base classes

Exposer des constructeurs par using quand la classe ancête visée est virtuellement héritée est... mal. La résolution est un bris d'ABI dans certains cas. L'exemple est ... périlleux. C'est pas des actions recommandables, mais espérons des avertissements à la compilation

Core Issue 2476 – placeholder-type-specifiers and function declarators

EWG a décidé d'ajourner avant de discuter de ceci...

Wording for FR-025-17 (relative to N4928)

On travaille sur le linkage de noms introduits dans certains types de fichiers, en particulier les modules. C'est mêlant parce que les mêmes sections ont été travaillées par d'autres propositions cette semaine. On remarque qu'il y a plus de noms qui obtiennent external linkage que ce que nous souhaiterions.

(on suspend pour la journée, il se fait tard; je ne sais pas si je vais revenir pour la séance de soirée, ça va dépendre de mon éveil... beaucoup de travail aujourd'hui!)

Jour 4 9 février 2023

On commence la journée de bonne humeur. J'ai jonglé plusieurs dossiers pour le travail plus tôt ce matin (ça pleut!)

L'enjeu des suffixes de littéraux maison revient (Core Issue 2521). Il semble que certaines manipulations de macros puissent causer d'autres incidents... Hé la la. Ça va revenir aujourd'hui. Il se peut qu'on doive être plus stricts encore.

On revient sur la question du linkage et des modules, et sur l'impact d'avoir des fonctions static définies dans un .h (c'est pas l'idée du siècle en C++). Évidemment, nous ne sommes pas là pour juger des pratiques des gens, malsaines ou pas.

Wording for FR-025-017

C'est le dossier chaud du matin, qui recoupe EWG et CWG car cette discussion est en partie évolutionnaire. On passe en revue le texte (dense) en essayant d'éviter les conflits avec C. Le terme « client » est défini en terme de modules; un module peut être client d'une déclaration. Le texte essaie de définir quand deux choses sont une seule et même chose. Davis Herring prend la peine d'expliquer la théorie et la motivation derrière les aspects (mutliples et subtils) de la proposition.

Après une heure de travail intense, Davis Herring se retire pour préparer des exemples (la proposition est hyper dense et exempte d'exemples!). On signale qu'on informera EWG des ajustements pour qu'ils puissent donner leur avis cet après-midi.

P2797 – Proposed resolution for CWG2692 Static and explicit object member functions with the same parameter-type-lists

Jason Merill explique que ceci règlerait deux Core Issues (Core Issue 2692 et Core Issue 2687) et un enjeu évolutionnaire. On l'examinera en après-midi, plus en détail, mais on examine un passage en particulier ce matin. Ça semble unifier les cas suivants (const ou pas) :

struct A {
  static void f(A); // #A
  void f(this A);   // #B

  static void e(A const&); // #C
  void e() const&;         // #D

  void g() {
    // static + explicit memfn
    (&A::f)(A()); // #1
    f(A());       // #2
    (&A::f)();    // #3

    // static + implicit memfn
    (&A::e)(A()); // #4
    e(A());       // #5
    (&A::e)();    // #6
  }
};

Jason Merill dit que EWG a décidé qu'on pourrait « moralement » réaliser l'Overload Resolution sur le résultat de la décrépitude de pointeur. Présentement, #1 est ambigu. La ligne #4 n'est pas ambiguë actuellement mais le deviendrait. C'est amusant comme enjeu : il y a un bogue dans certains compilateurs, on cherchait à le régler, Davis Herring a suggéré une piste différente à brûle-pourpoint, et... EWG a sauté dessus, anticipant en quelque sorte l'intégration de std::invoke() dans le langage plutôt que dans la bibliothèque!

Ça implique plusieurs conséquences surprenantes (le pointeur résultant aurait un sens différent selon l'endroit où il serait synthétisé)... et on se retrouve avec de nouvelles manières d'appeler une fonction!

Il y a dissension (cordiale) ici; c'est la faute de Davis Herring , vraiment, mais Jason Merill n'est pas d'accord (ils demeurent amis!)

(brêve pause de 15 minutes)

Je reviens avec cinq minutes de retard (gérer Pauline le chien, c'est pas toujours simple). On revient sur Core Issue 2687 (et on blague sur le fait que CWG est une sorte de Hive Mind, qui fonctionne par consensus). Après une demi heure de travail, Davis Herring signale que Deducing this, de C++ 23, a apporté des changements considérables sur le langage, et qu'il faudra s'ajuster pendant des années encore, quand bien même ce ne serait que dans le Core Language (mais on s'en doutait).

Hubert Tong fait remarquer que les parenthèses sont à considérer (ils changent le sens de « prendre l'adresse d'un membre »), mais Davis Herring signale que dans les cas que nous spécifions, le contexte est une fonction static (méthode de classe) alors ce n'est pas un enjeu.

Après une heure à retravailler l'algorithme, Jason Merill fait remarquer que ça ressemble à la manière dont nous trions habituellement nos fonctions dans un fichier pour obtenir un graphe acyclique dirigé de manière à faire l'économie de déclarations a priori.

C'est beaucoup de travail; Jens Maurer demande s'il s'agit d'un Core Issue, mais Jason Merill rappelle que certains mécanismes clés de C++ 23 ne fonctionneront pas sans ce correctif.

(pause dîner d'une heure; ils prennent la photo de C++ 23 là-bas alors je ne serai pas sur la photo cette fois encore)

Jens Maurer annonce que les enjeux qui ont occupé notre matin sont désormais discutés chez EWG.

On passe les Tentatively Ready Issues de cette semaine, mais rapidement (il y en a 24, alors avec cinq minutes chacune, ça fait deux heures)

(je ne note pas tout)

On en met quelques-unes de côté (parce que moins pressants, et susceptibles de jouer des tours), incluant Core Issue 1973, 2485, 2531 (qui demande qu'on l'implémente et qu'on l'essaie au préalable, par crainte de briser des éléments de C++ 17, alors ce sera un DR et on le passe de Tentatively Ready à Under Review), 2663,

Dans le cas de l'espace désormais interdit entre "" et _ pour les littéraux maison, le souhait de procéder à une dépréciation est un facteur à considérer (on essaie de donner du temps aux usagers pour s'ajuster) alors on va le proposer, mais séparément pour mettre en relief qu'il est particulier.

Dans le cas des comparaisons relationnelles entre void*, on garde la note non-normative mais on va investiguer ce qui se passe avec C.

Il y a des débats quant au caractère bénin ou pas de Core Issue 2528, mais on le proposera tout de même

La 2678 (source_location::current() est impossible à implémenter) sera aussi proposée séparément étant donné qu'il peut y avoir de la résistance. Cette chose étend la règle ODR.

On revient ensuite au dossier (considérable!) de ce matin sur les Overload Resolution modifiées depuis l'avènement de Deducing this (D2797). On examine l'option d'en extraire une petite partie qui deviendrait un Core Issue, pour garder le coeur du changement en vue d'une proposition pour vote demain. On réexamine le problème original (Core Issue 2687) qui proposait :

struct A {
   void f(this A);
   static void f(A);
   void g();
};
void A::g() {
   (&A::f)(A())); // #1
   (&A::f)(); // #2
}

... et disait que bien qu'il soit clair que #2 soit incorrect, #1 semble moins évident. On y va par vote (chose rare chez CWG) : maintenant ou plus tard? Et la majorité va pour maintenant. On continue à le regarder; le texte est tel que (&C::c)() et (&(C::c))() ne sont pas soumis aux mêmes règles (le second est l'adresse d'un Overload Set)... Ouf. Je vérifie si les règles sont les mêmes dans la mesure où le code de l'exemple maudit que nous regardons se trouve logé dans une IIFE (j'ai peur!), mais il semble que ce soit le cas (au moins!)

Après beaucoup de travail sur D2797, les exemples qui sont légaux et ceux qui ne sont pas légaux ne sont plus tout à fait les mêmes. L'exemple final est par contre bien meilleur :

class C {
   void c(this const &C); // #1
   void c() &;            // #2
   static void c(int i = 0);  // #3
   
   void d() {
      c(); // ambiguous between #2 and #3
      (C::c)(); // error, as above
      (&C::c)(C{}); // selects #1
      (&C::c)(*this); // selects #2 and is ill-formed
      (&(C::c))(); // error : address of an overload set
      (&C::c)(); // selects #3      
   }
};

(je dois m'absenter pour une heure – incluant la pause – pour raisons familiales; à mon retour, on discute de P2593 qui permettra d'utiliser static_assert(false) dans une branche non-générée d'un if constexpr). L'idée est de faire (enfin!) compiler ceci :

template <class T>
   void f(T arg) {
      if constexpr(sizeof(T) == sizeof(int))
         use(arg);
      else
         static_assert(false, "must be int-sized");
   }
// ...
void g(char c) {
   f(0); // Ok
   f(c); // error, must be int-sized
}

... même si le false ne dépend pas de T. Il y a des liens avec #error et #warning alors on se demande si on les passe en bloc, séparément, si on attend... On vote et on dit unanimement « oui, on fonce » alors il se peut que ça bloque demain. Notez qu'il y a une différence entre ceci :

template <class T> void f(T) {
   if constexpr(sizeof(T) == 2) {
      static_assert(false); 
   }
}

... qui compile, et cela :

template <class T> void f(T) {
   if constexpr(sizeof(T) == 2) {
#error "oops"
   }
}

... qui ne compile pas, car ce qui commence par un # est traité par le préprocesseur (bien avant que le compilateur n'ait accès au texte).

On convient que tout cela est un DR... pour C++ 20.

Core Issue 2308 (paper 2450) – Template Parameter Initialization

Ça parle des NTTP de C++ 20. En gros, c'est un micro ajustement à la grammaire pour permettre d'utiliser {} pour les valeurs par défaut de paramètres de templates si c'est une expression constexpr. L'algorithme est subtil car il doit tenir compte de l'importance des adresses dans ces paramètres, ce qui importe par exemple si on doit comparer deux pointeurs dans un même tableau

(j'ai dû quitter à 20 minutes de la fin)

Jour 5 – 11 février 2023

C'est la fin de cette grosse semaine, et nous serons en plénière à 8 h 30 heure d'Issaquah (11 h 30 heure de Montréal) pour voter sur les résolutions de CWG, LWG (dont un un peu différent des autres car il portera sur la Concurrency TS v2) et sur deux résolutions de WG21. Je passe quelques heures à préparer ce qui suit pour noter les décisions qui seront prises.

Je me connecte une quinzaine de minutes d'avance et il y a déjà quelques participant(e)s. John Spicer, Chair de WG21, prépare la présentation de ce matin. On apprend qu'on prendra une photo des participants Zoom tantôt alors je serai là si la technique tient la route!

On fait le tour des rapports des groupes d'étude :

On discute brièvement de trucs administratifs, par exemple signaler notre présence si ce ne fut fait

On poursuit avec les groupes de travail :

Votes du CWG

Les fruits de cette semaine de travail suivent.

1. Accept as a Defect Report and apply the proposed resolution of all issues except issues 2518, 2521, 2659, 2674, 2678, 2687, 2691 in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

Adopté à l'unanimité

2. Apply the proposed resolution of issues 2674, 2687, 2691 in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

Adopté à l'unanimité

3. Accept as a Defect Report and apply the proposed resolution of issue 2518 (Conformance requirements and #error/#warning) in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

Ville Voutilainen signale qu'il lui semble déplaisant que l'on intègre des Breaking Changes a posteriori. Vote demandé : consensus

4. Accept as a Defect Report and apply the proposed resolution of issue 2521 (User-defined literals and reserved identifiers) in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

Vote demandé (sans surprises, c'est un peu controversé) : consensus, mais avec plusieurs abstentions

5. Accept as a Defect Report and apply the proposed resolution of issue 2678 (std::source_location::current is unimplementable) in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper.

Adopté à l'unanimité

6. Apply the proposed resolution of issue 2659 (Missing feature-test macro for lifetime extension in range-for loop) in P2796R0 (Core Language Working Group "ready" Issues for the February, 2023 meeting) to the C++ Working Paper, resolving NB comment DE-038.

Adopté à l'unanimité

7. Specify that P2647R1 (Permitting static constexpr variables in constexpr functions) (applied in November, 2022) is no longer a Defect Report.

On demande si CWG a considéré faire du feature sur lequel cela dépend un DR, pour que ce mécanisme puisse être intégré à C++ 20 a posteriori. Jens Maurer dit que ça a été discuté mais que ça n'a pas passé. Herb Sutter rappelle que si on avait fait cela, il aurait fallu passer par EWG.

Adopté à l'unanimité

8. Apply the changes in P2736R2 (Referencing The Unicode Standard) to the C++ Working Paper, resolving NB comments FR-010-133 and FR-021-013.

Adopté à l'unanimité

9. Accept as a Defect Report and apply the changes in P2788R0 (Linkage for modular constants) to the C++ Working Paper, resolving NB comment US 8-036.

Adopté à l'unanimité

10. Apply the changes in P2797R0 (Proposed resolution for CWG2692 Static and explicit object member functions with the same parameter-type-lists) to the C++ Working Paper.

Adopté à l'unanimité

Votes de LWG

Grosse semaine où tout le matériel pour C++ 23 a été traité. Des efforts investis sur Senders / Receivers et sur C++ 26 aussi. Outre la TS, la plupart des trucs sur la table aujourd'hui sont des Bug Fixes.

Le premier vote porte sur la Concurrency TS v2. Les autres portent sur C++ 23.

1. Apply the changes in P0290R4 (synchronized value) to the Concurrency TS v2 working paper.

Adopté à l'unanimité

2. Apply the changes for all Ready and Tentatively Ready issues in P2789R0 (C++ Standard Library Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

Adopté à l'unanimité

3. Apply the changes for all Immediate issues except 3441 in P2790R0 (C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

Adopté à l'unanimité

4. Apply the changes for the Immediate issue 3441 in P2790R0 (C++ Standard Library Immediate Issues to be moved in Issaquah, Feb. 2023) to the C++ working paper.

Adopté à l'unanimité

5. Apply the changes in P2770R0 (Stashing stashing iterators for proper flattening) to the C++ working paper. This addresses ballot comment US 61-126.

Adopté à l'unanimité

6. Apply the changes in P2164R9 (views::enumerate) to the C++ working paper. This addresses ballot comments FR 14-021 and US 48-108.

Vote demandé : consensus (mais beaucoup d'absentions)

7. Apply the changes in P2711R1 (Making multi-param constructors of views explicit) to the C++ working paper.

Adopté à l'unanimité

8. Apply the changes in P2609R3 (Relaxing Ranges Just A Smidge) to the C++ working paper. This addresses ballot comment US 39-099.

Adopté à l'unanimité

9. Apply the changes in P2713R1 (Escaping improvements in std::format) to the C++ working paper. This addresses ballot comments US38-098 and FR005-134.

Adopté à l'unanimité

10. Apply the changes in P2675R1 (format's width estimation is too approximate and not forward compatible) to the C++ working paper. This addresses ballot comment FR-007-012.

Adopté à l'unanimité

11. Apply the changes in P2572R1 (std::format fill character allowances) to the C++ working paper.

Adopté à l'unanimité

12. Apply the changes in P2693R1 (Formatting thread::id and stacktrace) to the C++ working paper. This addresses ballot comment FR-012-023.

Vote demandé : consensus (plusieurs abstentions)

13. Apply the changes in P2679R2 (Fixing std::start_lifetime_as for arrays) to the C++ working paper. This addresses ballot comment CA-086.

Vote demandé : consensus (plusieurs abstentions)

14. Apply the changes in P2674R1 (A trait for implicit lifetime types) to the C++ working paper. This addresses ballot comment GB-089.

Vote demandé : consensus (plusieurs abstentions)

15. Apply the changes in P2655R3 (common_reference_t of reference_wrapper Should Be a Reference Type) to the C++ working paper.

Adopté à l'unanimité

16. Apply the changes in P2652R2 (Disallow User Specialization of allocator_traits) to the C++ working paper. This addresses ballot comment US 33-077.

Adopté à l'unanimité

17. Apply the changes in P2787R1 (pmr::generator - Promise Types are not Values) to the C++ working paper. This addresses ballot comment US 53-116.

Vote demandé : consensus (plusieurs abstentions)

18. Apply the changes in P2614R2 (Deprecate numeric_limits::has_denorm) to the C++ working paper. This addresses ballot comment DE-079.

Adopté à l'unanimité

19. Apply the changes in P2588R3 (barrier’s phase completion guarantees) to the C++ working paper. This addresses ballot comment DE-135 and US 63-131.

Vote demandé : consensus (plusieurs abstentions)

20. Apply the changes in P2763R1 (layout_stride static extents default constructor fix) to the C++ working paper.

Adopté à l'unanimité

Votes de WG21

Deux votes touchent WG21 dans son ensemble.

Poll 1 – Appoint a review committee composed of Jonathan Wakely, Daniel Krügler, and Bryan St. Amour to approve the correctness of the Working Paper for C++ Extensions for Concurrency, version 2 as modified by the polls approved at this meeting, and direct the Convener to transmit the approved updated Working Paper for PDTS ballot.

Adopté à l'unanimité

Poll 2 – Appoint a review committee composed of Daniel Krügler, Nina Ranns, Michael Hava, and Jonathan Wakely to approve the correctness of the C++ working paper as modified by the polls approved at this meeting, and direct the Convener to transmit the approved updated working paper for DIS ballot.

Adopté à l'unanimité

Autres objets de discussion

Herb Sutter remercie tous les gens qui ont participé aux travaux à travers la pandémie. On s'applaudit, et on prend la photo par Zoom (ça prend deux écrans!)

On examine certains dossiers administratifs (p. ex. : on nous permet la retranscription automatique, mais est-ce en contravention des permissions de noter ce qui se passe pendant que ça se passe? ISO nous dit de ne pas l'enregistrer pour le moment)

La prochaine rencontre in vivo envisageable est Varna (Bulgarie), organisé entre autres par VMWare en juin 2023 (https://wg21.link/n4935)  puis Kona (É.-U.) en novembre 2023.

On souligne (avec raison!) que nous avons réussi encore une fois à respecter le rythme de trois ans pour chaque version de C++ depuis 2011. Quand même...!


Valid XHTML 1.0 Transitional

CSS Valide !