À propos de WG21, Kona 2025 (novembre)

Je participe à cette rencontre à distance. La rencontre de cette semaine se tenant à Kona (Hawaii), le décalage horaire sera rude, et j'ai des dossiers à défendre alors ce sera une semaine quelque peu... physique. Je ne serai que partiellement présente à cette rencontre alors soyez tolérantes et tolérants envers moi s.v.p.

Les principaux thèmes de la rencontre sont la finalisation des travaux pour C++ 26, en particulier la réflexivité statique et – surtout – les contrats. Je devrais passer ma semaine chez CWG comme à mon habitude. J'ai des dossiers à défendre en vue de C++ 29 mais je n'ai pas réussi à les faire progresser suffisamment au cours des derniers mois pour présenter de nouvelles révisions cette semaine.

Ce sera la dernière présence de Herb Sutter à titre de Convener, celui-ci cédant sa place à Guy Davidson à partir de la prochaine fois.

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 – 3 novembre 2025

L'horaire de cette semaine est intéressant pour le maintien de la plupart de mes activités professionnelles car j'enseigne souvent le matin et 8 h 30 à Kona, c'est 13 h 30 à Montréal. En retour, les journées là-bas se termineront à 22 h pour moi 🙂

John Spicer fait l'accueil comme il se doit. Herb Sutter explique qu'une équipe de cinéastes est sur place pour tourner un documentaire sur C++, mais ne sera évidemment pas présent dans les salles où nous discutons de sujets techniques. Il explique aussi le rôle de cette rencontre, qui est d'accroître le consensus en vue de C++26 en offrant une réponse à chacun des NB Comments reçus. Herb Sutter explique qu'il laissera le plus d'espace possible à son remplaçant, Guy Davidson, qui sera le Convener de WG21 désormais. Inbal Levi annonce que LEWG pourrait ne pas être en mesure de traiter tous ses NB Comments alors il est possible que le travail soit complété à travers des téléconférences.

On présente le code de conduite (avec l'aide de notre secrétaire Nina Ranns, qui fait toujours un excellent travail!), les règles lors des votes, on laisse les nouveaux membres et les invité(e)s se présenter. On présente l'organisation de la semaine et la répartition des groupes d'études comme des groupes de travail dans les diverses salles. C'était essentiellement la routine habituelle, à ceci près qu'on n'a pas de séance de soirée prévue pour le moment (étrange...). On apprend que Nina Ranns devient vice-Convener alors il nous faudra une nouvelle personne pour jouer le rôle de secrétaire (je l'ai fait deux fois déjà, mais je ne suis pas toujours capable de participer en personne).

Le gros morceau de la semaine est le traitement des NB Comments de C++26. Le dossier le plus chaud est probablement celui des contrats, acceptés à la plus récente rencontre mais auxquels certains pays s'opposent.

La plénière se termine et les gens se déplacent vers les salles où se tiendront les travaux qui les touchent le plus. Pour moi, ce sera CWG comme à l'habitude.


J'arrive un peu d'avance (se déplacer virtuellement, ça va vite!). La page Wiki de CWG est encore vide, mais évidemment ce sera une semaine très remplie. On s'assure que la technique fonctionne bien et comme c'est toujours le cas, c'est excellent une fois le rodage fait. On doit bien sûr traiter les NB Comments en priorité, mais il faudra gérer les présences car certains membres importants de CWG sont chez EWG pour les (chaudes!) discussions sur les contrats.

BR13

Ceci demande d'appliquer P3579R2: Fix matching of constant template parameters when matching template template parameters telle quelle. L'enjeu est :

template<template<short> class> struct A {};

template<short> struct B;
template struct A<B>; // OK, exact match

template<int> struct C;
template struct A<C>; // #1: OK, all 'short' values are valid 'int' values

template<char> struct D;
template struct A<D>; // #2: error, not all 'short' values are valid 'char' values

Le cas #2 est accepté en ce moment, et la proposition est de le rejeter. De même :

template<template<short> class TT1> void f(TT1<0>); // #1
template<template<int> class TT2> void f(TT2<0>);   // #2

template<int> struct B;
template void f<B>(B<0>); // selects #2

Auparavant, ceci choisissait #2. Désormais, c'est ambigu. La proposition est de corriger cette situation. On examine les changements proposés pour voir si ça fait ce qui est attendu. On se questionne beaucoup : les règles pour le Partial Ordering des règles de résolution dans ces situations sont complexes. Hubert Tong se questionne sur le problème en soi : il se limite aux narrowing conversions, de un, mais Hubert Tong semble penser que le problème présenté n'en est pas un de langage mais bien un bogue de compilateur.

On regarde https://eel.is/c++draft/temp.deduct.type#20 qui semble pertinent.

Après près d'une heure et demie de travail et de discussions, nous ne sommes pas convaincus que nous pouvons traiter ce dossier cette semaine, et recommandons un retour chez EWG pour confirmer qu'il est pertinent de traiter cela en tant que NB Comment (les impacts sur le design semblent susceptibles de surprendre). Il est possible qu'on le revisite si on confirme que les présupposés de ce NB Comment sont erronés (à confirmer)

US 286-402

Jens Maurer explique que c'est un de plusieurs NB Comments dans la même direction, mais que ceux-ci demanderont un examen par EWG au préalable.

US 126-189

Ceci recoupe https://eel.is/c++draft/meta.reflection.define.aggregate#8 et il y a un enjeu de logique circulaire (on définit quelque chose qui touche aux types incomplets, on discute de spécialisations, et l'acte qui rend un type incomplet « complet » est le geste de l'examen réflexif de sa spécialisation). L'acte d'examiner quelque chose de constant le rend non-constant avec le texte existant. Il faudra ajouter une remarque

FR 017-155

C'est une requête de nommer les fonctions variadiques d'un Core Term. Ceci fut discuté dans une téléconférence et le terme choisi fut vararg function.

RU 153

On parle de permettre la métaprogrammation Stateful à travers friend injection. On avait interdit ceci, mais en pratique les diverses étapes qui permettent de faire cela semblent valides; le problème est qu'en combinant ces étapes d'une certaines manière, on en arrive à cette technique surprenante.

Hubert Tong pense qu'on n'a pas à traiter ceci, le NB Comment ne démontrant pas pourquoi c'est important de régler cela maintenant. On a l'impression que le demandeur est d'avis que la réflexivité montre que ceci devraît être accepté dès C+++26. On le revisitera dans un autre contexte.

(pause dîner; je prépare le souper de la famille et j'accueille mon plus jeune Ludo qui revient de l'école)

US 59

On parle de l'ordre d'évaluation de # et de ## dans le préprocesseur : quand on a plusieurs occurrences de ces opérateurs, l'ordre d'évaluation n'est pas spécifié. Le texte est dans [cpp.stringize].

Hubert Tong est d'avis que c'est un « non-problème » dans certains cas, mais on identifie des cas où le problème existe. On n'a par contre pas de recommendation pour un ordre ou l'autre, alors on passerait d'un cas de Unspecified à un cas de Implementation-Defined.

On envisage parler aux membres de WG14, mais ils ont le même texte que nous dans ce cas. On apprend que certains compilateurs ont plus d'une stratégie selon la complexité de la macro à traiter, ce qui complique encore plus le portrait. On jongle avec l'idée de demander aux implémentations de documenter leur comportement, dans l'espoir que tout le monde fasse la même chose... et qu'on la standardise!

Ça ne progressera pas plus cette semaine, manifestement.

US 57

Cela correspond au Core Issue 3088. Clarify macro treatment of identifiers with special meaning qui rend (rétroactivement) illégal le recours à un identifiant portant un Special Meaning dans une macro. Le problème est que la compilation procède par phases et qu'on veut interdire en phase 4 des identifiants qui sont connus en phase 7.

Le texte sur la table semble pas mal.

US 56

On parle de Ill-formed private module fragments. Jens Maurer pense que le problème est une lecture incorrecte de la grammaire. (j'ai perdu quelques minutes en servant le souper aux enfants).

 À  mon retour, on semble en train de rediscuter BR13 de ce matin; on a une tension entre spécification et implémentation. Ceci recoupe Core Issue 2900 :

template<auto> struct C;
  template<long long x> void f(C<x> *);
  void g(C<0LL> *ap) {
    f(ap);     // OK, deduces long long value from 0LL
  }

  template<int> struct D;
  template<auto x> void f(D *);
  void g(D<0LL> *ap) {
    f(ap);   // OK, deduces x as an int value
  }

  template<int &> struct E;
  template<auto x> void f(E<x> *);
  int v;
  void g(E<v>; *bp) {
    f(bp);    // error: type int of x does not match the int & type of the template parameter in the E<v> specialization of E
  }

  template<const int &> struct F;
  template<decltype(auto) x> void f(F<x> *);
  int i;
  void g(F<i> *ap) {
    f(ap);   // OK, deduces x as a non-type template parameter of type const int &
  }

  template <decltype(auto)> struct G;
  template <auto x> long *f(G<x> *);   // #1
  template <decltype(auto) x> short *f(G<x> *); // #2

  const int j = 0;
  short *g(G<(j)> *ap) {
    return f(ap);     // OK, only #2 matches
  }

  long *g(G<j> *ap) {
    return f(ap);     // OK, #1 is more specialized
  }

C'est pas la section la plus digeste du Core Language (auto est « plus spécialisé » que decltype(auto).... oh boy). On travaille fort, et on convient qu'on va accepter une version amendée de la proposition.

US 54

La demande est Define Immediate Context. C'est un terme qui sert souvent, mais dont la définition formelle manque un peu d'amour. Ça permet entre autres de déterminer ce qu'une expression λ peut capturer. Ça rejoint Core Issue 1844. On exclut les paramètres avec valeurs par défaut (Core Issue 2296) parce que c'est bloqué chez EWG. On semble avoir quelques cas problèmes comme ça...

(on apprend que les discussions sur les contrats sons suspendues pour le moment, mais qu'elles reprendront demain)

AT 4

On parle d'un enjeu d'initialisation de Structured Bindings avec des initialiseurs non-dépendants. Ça a été travaillé par le passé. On semble à l'aise d'apporter ceci pour votre en plénière.

AT 3

Ceci rejoint Core Issue 3095: Type-dependent packs that are not structured binding packs. On parle d'un très petit changement. Dans le standard, ça recoupe [temp.dep.expr#3.6].

US 53

On a un enjeu grammatical mineur dans [temp.dep.expr#3.11]. Ça semble éditorial

FR 007

Ceci correspond à Core Issue 2917: Disallow multiple friend specifiers for a template, et ça vise à traiter un cas comme :

template<class ...>
struct C {
  struct Nested { };
};

template<class ... Us>
struct S {
  template <typename ...Ts>
  friend class C<Ts>::Nested...;     // error
  friend class C<Us>::Nested...;     // OK
};

Brian Bi attrape un cas qu'on a échappé (merci!).

US 52

Le titre est Designates / names for alias templates, suggérant que l'on ne soit pas cohérent dans notre choix de mots. On penche pour rejeter, et on regarde le texte existant pour valider notre hypothèse.

CA 94

Ceci connecte à Core Issue 3021: Subsumption rules for fold expanded constraints. L'enjeu est :

template <typename T>
  concept C = false;

  template <typename ...T>
  concept CC = (C<T> && ...);

  template <typename T> requires CC<T>
  struct A;

  template <typename T> requires CC<> && true
  struct A<T>; // okay, surprisingly

Il nous manque un membre pour régler cela aujourd'hui.

US 37

Le titre est Differentiate plain-text "declaration" from grammar "declaration". C'est un problème de... police de caractères. Faut quand même le régler!

(pause d'après-midi)

(j'ai manqué le début du dernier bloc de travail; à mon retour, on parle de grammaire, en particulier de template-declaration, et on regarde la prose dans [basic.def]. La prose semble incorrecte en suggérant qu'une déclaration vide soit une déclaration, ce qui n'est pas le cas. On élimine une puce dans une note. Pour le reste, on n'a pas de consensus alors ce sera remis à plus tard.

DE 068

On parle de Fix Expansion Statements, ou Core Issue 3043 (entre autres). L'objet est la durée de vie des objets générés par un for-range-initializer et, par extension (pour le moment) par un template for. On se demande si on souhaite vraiment une extension de la durée de vie de chacune des variables générées (et si oui, une extension jusqu'à quand?). Les débats durent près d'une heure. Il y a une interaction inattendue avec les objets constexpr (qui verraient leur vie devenir infinie!)., On jongle avec plusieurs options, et on clarifie le propos.

US 33

On demande Specify timing of constant evaluation. On discute et... on finit par rejeter.

US 19

(je commence à être fatigué, mais il est 21 h 26 heure de Montréal et les travaux se terminent dans une trentaine de minutes; je vais aller faire une sieste avant d'aller chercher Viktor, mon 4e enfant. au boulot vers 23 h)

Jour 1 – 4 novembre 2025

J'enseignais en avant-midi et j'avais un rendez-vous médical familial en après-midi alors je me suis joint à CWG en début d'après-midi heure de Kona (vers 18 h 15 heure de Montréal). À mon arrivée, on examine https://eel.is/c++draft/expr.ref#10 en lien avec Core Issue 3093. Ça touche aux Splice Expressions qui apparaissent avec la réflexivité statique de C++26. Je n'ai pas le détail mais ça semble prêt pour vote. Je pense que les discussions sur les contrats ont draîné notre quorum 🙂

Core Issue 3114: Indirect base classes for class member access with direct base class relationship

C'est une Core Issue toute fraîche (elle date d'hier!). C'est une subtilité : le texte est « Subclause 7.6.1.5 [expr.ref] bullet 8.6 does not specify what happens if the direct base class relationship originates from an unambiguous base class of E1. ». Un problème par omission? On retravaille un peu le texte (il manque des trucs dans ce qui est proposé, mais dans le contexte du standard on parle de relations en situation de réflexivité). Un peu de travail et c'est prêt pour vote samedi.

Hubert Tong fait remarquer que la même manoeuvre doit s'appliquer à [over.ref] alors il y aura des retouches plus tard cette semaine.

Core Issue 2900: Deduction of non-type template arguments with placeholder types

On parle de NTTP avec auto et decltype(auto). Il semble y avoir des trous dans les règles. L'exemple proposé est complexe :

template<int i> class A { /* ... */ };
  template<short s> void f(A<s>);
  void k1() {
    A<1> a;
    f(a);      // error: deduction fails for conversion from int to short
    f<1>(a);   // OK
  }
  template<const short cs> class B { };
  template<short s> void g(B<s>);
  void k2() {
    B<1> b;
    g(b);  // OK, cv-qualifiers are ignored on template parameter types
  }


  template<auto> struct C;
  template<long long x> void f(C<x> *);
  void g(C<0LL> *ap) {
    f(ap);     // OK, deduces long long value from 0LL
  }

  template<int> struct D;
  template<auto x> void f(D<x> *);
  void g(D<0LL> *ap) {
    f(ap);   // OK, deduces x as an int value
  }

  template<int &> struct E;
  template<auto x> void f(E<x> *);
  int v;
  void g(E<v> *bp) {
    f(bp);    // error: type int of x does not match the int & type of the template parameter in the E<v> specialization of E
  }

  template<const int &> struct F;
  template<decltype(auto) x> void f(F<x> *);
  int i;
  void g(F<i> *ap) {
    f(ap);   // OK, deduces x as a non-type template parameter of type const int &
  }

  template <decltype(auto)> struct G;
  template <auto x> long *f(G<x> *);   // #1
  template <decltype(auto) x> short *f(G<x> *); // #2

  const int j = 0;
  short *g(G<(j)> *ap) {
    return f(ap);     // OK, only #2 matches
  }

  long *g(G<j> *ap) {
    return f(ap);     // OK, #1 is more specialized
  }

Un problème de fond est celui du Partial Ordering entre une déduction de auto et une déduction de decltype(auto). C'est embêtant, et la solution correcte ne saute pas aux yeux. On cherche une règle qui permet de préférer template<int> à template<auto> mais n'interfère pas avec template<decltype(auto)>. Juste donner une règle ne suffit pas parce qu'un même template pourrait avoir plusieurs paramètres!

Core Issue 2917: Disallow multiple friend-type-specifiers for a friend template

Il y a eu des travaux hier soir à ce sujet. On en est rendus à « In a template-declaration whose declaration is a friend-type-declaration, the friend-type-specifier-list shall consist of exactly one friend-type-specifier and that friend-type-specifier shall not be a pack expansion. » avec l'exemple suivant :

template<class ...>
struct C {
  struct Nested { };
};

template<class ... Us>
struct S {
  template <typename ...Ts>
  friend class C<Ts>::Nested...;     // error
  friend class C<Us>::Nested...;     // OK, not a template-declaration
};

On est embêtés par une formulation, mais Hubert Tong trouve une approche qui simplifie beaucoup le texte (bravo!). Ça s'en va au vote samedi.

Core Issue 3115: Function parameters of consteval-only type

On parle d'un mécanisme très novateur pour lequel le texte demande un peu de polissage. Par exemple, est-ce qu'une fonction qui accepte un paramètre consteval-only peut être exécutée à l'exécution? Ça semble improbable.

On pense que le texte proposé est le bon. On le votera samedi.

Core Issue 3043: Lifetime extension for temporaries in expansion statements

Les expansion statements (les for...) produisent des tas d'objets et on s'interroge sur leur durée de vie. Par exemple, est-ce que chaque objet vit jusqu'à la fin de « son » expansion ou est-ce qu'ils vivent tous jusqu'à la fin de l'expansion entière? C'est cette dernière option qu'on semble privilégier (c'est probablement sage).

On enverra ça pour vote samedi.

Core Issue 3099: Instantiation of type aliases from alias templates is unspecified

Un autre enjeu en lien avec la réflexivité :

#include <meta>

using namespace std::meta;

template <typename T> using A = T *;

template <auto> struct Sink;

template <typename T> void f(Sink<^^A<T> > * = 0); // immediately instantiated and considered as part of the immediate context?
template <typename T> void f(int = 0);
void g() { f<int &>(); }

constexpr auto x = substitute(^^A, {^^int &}); // valid until dealias?

L'enjeu est le moment où se produit l'instantiation, et l'impact du contexte avoisinant. Avant la réflexivité, il n'était pas possible en C++ de déclarer un alias sans le définir, alors ce problème est tout à fait novateur. Shafik Yaghmour nous rapporte que tous les compilateurs aujourd'hui plantent sur la dernière ligne!

On fait un choix (c'est pas légal!) et on le soumettra au vote samedi.

3111: Template parameter objects of array type

L'enjeu est de permettre la réflexivité sur des tableaux avec std::meta::constant_of() alors que pour les paramètres de templates, on a du Pointer Decay et on n'a donc jamais de tableaux dans ce contexte! La proposition consiste en un petit ajustement terminologique et... une note non-normative pour le cas des tableaux.

La proposition se tient mais certains expriment un malaise sur sa formulation alors on travaille sur une alternative qui nous semblerait plus claire. Un des enjeux est qu'on aimerait dire qu'un tel paramètre n'est pas véritablement à considérer s'il ne correspond pas à un objet du programme, or certains objets n'ont pas de nom mais existent tout de même. C'est embêtant. On trouve une reformulation plus heureuse. Ça recoupe la définition de template-parameter-equivalent.

On envoie ça pour vote samedi

(pause de milieu d'après-midi)

3110: Constexpr allocation for literal types

L'enjeu est que ceci devrait compiler, et compile en pratique, mais ne le devrait pas car std::locale n'est pas un type littéral :

#include <locale>
#include <memory>

static_assert([]{
   auto a = std::allocator<std::locale>{};
   a.deallocate(a.allocate(42), 42);
   return true;
}());

Rien de majeur à l'oeil, mais on en reparlera plus tard cette semaine étant donné les autres priorités.

3109: Access checking when designating a protected member by a splice

On a une règle qui semble couvrir les membres protégés mais ne le devrait probablement pas. Ça semble prioritaire pour cette semaine. Brian Bi propose une résolution. Il y a des nuances entre denotes et designates quand à la visibilité des membres lors d'une tentative d'accès (le terme denotes ne s'applique qu'aux noms; on débat de la capacité de designates de voir à travers les alias). On travaille le tout et on est satisfaits.

3107: Misleading note "An alias template name is never deduced."

On a une phrase un peu malheureuse et imprécise (elle affirme quelque chose pour lequel il existe des contre-exemples). La proposition de correctif est examinée. C'est bon.

3106: Redundant exclusion of (non-existent) UCNs in r-char-sequences

Prêt pour vote. Ça corrige un bogue dans le préprocesseur.

3105: Consteval destructor through immediate escalation

On a un problème avec ce qui suit car on ne sait pas ce que serait un destructeur consteval tôt dans une escalation immédiate :

consteval void undefined();
template <typename T>
  struct scope_exit {
    T t;
    constexpr ~scope_exit() { t(); }   // #2
  };

scope_exit guard([]() { 
  undefined();                       // # 1
});

Le texte accompagnant l'exemple est « #1 is an immediate escalating expression (because undefined is not defined) and ~scope_exit() is instantiated from a constexpr templated entity #2, thus is immediate escalating. Finally, this causes ~scope_exit to be an immediate function. However, destructors cannot be consteval. »

On identifie un problème dans la formulation de la résolution proposée (elle bloquerait la production de diagnostics pertinents). On corrige. Prêt pour vote.

3103: Corresponding members and by-value object parameters

C'est embêtant... Ceci est Ill-Formed :

struct K {
  void f(this K);
  void f();
};

... mais ceci ne l'est pas :

struct OK {
  void f(this OK);
  void f() &;
};

On en fait un enjeu de priorité 1 et on y reviendra.

3102: Update list of void contexts

On a une liste des cas où une expression de type void est permise (c'est [basic.fundamental] clause 6.9.2) et elle n'est pas à jour. C'est une clause un peu redondante, alors peut-être qu'une note non-exhaustive suffit. Je suis d'accord. Tentatively ready.

3101: Types "compounded" from other types

Le terme compounded, comme dans compounded-from pour les types consteval, est mal défini. On le remplace par une liste de cas.

3081: Require glvalue when splicing direct base class relationship

C'est un enjeu de précision, mais la proposition semble convenir. Ça ressemble à d'autres trucs qu'on a couverts cette semaine mais après un peu d'investigation, ça semble être un dossier à part entière. Tentatively Ready.

3079: Allow empty-declarations in anonymous unions

L'exemple dit tout :

struct A { union {int x;;} u; };    // OK
struct B { union {int y;;}; };      // error

La résolution est triviale. Tentatively Ready.

3078: Different treatment of #include pp-tokens and header-name-tokens

Une aberration du préprocesseur en présence de digraphes. On pense que c'est pas mal comme résolution, mais on va attendre d'avoir plus d'implémenteurs dans la salle pour trancher.

3073: Dependence of R on T2 is unclear

Un enjeu de clarification dans le cas de fonctions de conversion. C'est un peu abstrait : le texte utilise des « variables » dans sa prose et leur relation n'est pas limpide. Il y a des subtilités dans les règles (j'entends des soupirs dans la salle!). On le lit plusieurs fois... Tentatively Ready.

3072: Incorrect examples for lambda SFINAE

On a des exemples incorrects :

template <class T>
  auto h(T) -> decltype([x = T::invalid]() { });
void h(...);
h(0);   // error: invalid expression not part of the immediate context OK, calls h(...)

template <class T>
  auto i(T) -> decltype([]() -> typename T::invalid { });
void i(...);
i(0);   // error: invalid expression not part of the immediate context OK, calls i(...)

template <class T>
  auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1
void j(...);      // #2
j(0);   // deduction fails on #1, OK, calls #2 j(...)

On valide le tout pour éviter de faire une bêtise. Ça semble bon.

3071: Negative tuple_size in structured bindings

C'est pas gentil : le texte n'offre aucune protection contre un tuple_size négatif, mécanisme pour lequel il existe un protocole :

namespace std {
  template <typename T> struct tuple_size;
  }

struct S {
  int a;
};

template <> struct std::tuple_size<S> {
  static constexpr int value = -1;
};

void f(auto) { auto [... a] = S{}; } // ouch

Le texte proposé nous convient. Tentatively Ready.

3070: Trivial assignment can skip member subobjects

Quelqu'un a trouvé le moyen de contourner la trivialité de l'affectation =default... Hé la la :

struct B0 { int b0; };

struct B {
  B &operator=(const B &) = default;
  int x;
};

struct D : B0, B {
  using B::operator=;
private:
  D &operator=(const D &) && = default;
};

struct Q {
  Q &operator=(const Q &) = default;
  D d;
};

C'est astucieux... et pervers. On suggère de dire que dans un tel cas, l'affectation n'est pas triviale. Devrait-on la rendre =delete?

On essaie de cerner les cas qui peuvent nous mener là. Va falloir revenir là-dessus.

3069. Reference to wrong placeholder

C'est un enjeu terminologique avec les paramètres des concepts, particulièrement ceux avec des « valeurs » par défaut. Hubert Tong rapelle qu'une partie de l'enjeu ici est qu'on cherche à préserver l'identité des paramètres, et que l'identité dans le cas de paramètres par défaut est un sujet qui mérite réflexion.

On classe ça priorité 1.

3068: Access checking in friends involving qualified-ids

C'est amusant, ça. On a divergence d'implémentation sur :

class D {
    class E {
      class F {};
      friend void foo1(D::E::F& q);
    };
    friend void foo1(D::E::F& q);
  };
  void foo1(D::E::F& q) {}

... à savoir d'où vient le nommage de foo1(), et sur :

class G {
  using T = int;
  friend void foo(T);
};

class H {
  friend void foo(G::T);
};

... à titre d'exemple. Priorité 2.

On ferme les livres pour aujourd'hui.

Jour 2 – 5 novembre juin 2025

J'enseignais en avant-midi et j'enseigne ce soir, mais j'ai pu arriver à temps pour la séance matinale selon l'heure de Kona. Je pourrai donc participer à la première moitié de la journée aujourd'hui. On fait l'accueil, on prend les présences, et on se met au boulot.

Core Issue 3093: Missing integration of direct base class relationships

Il y a eu des développements depuis hier. C'est un petit ajout mais ça clarifie le texte. Merveilleux! Tentatively Ready.

Core Issue 2900: Deduction of non-type template arguments with placeholder types

On cherche toujours à établir un ordre partiel entre auto et decltype(auto) en considérant auto comme le plus spécialisé des deux. On a du texte pour les objets, mais les paramètres de templates sont une bestiole bien différente. Jens Maurer signale qu'on a d'autres problèmes dans cette section, et que celui-ci est simplement le plus visible d'entre eux.

À court terme, on pense simplement faire d'un paramètre de template decltype(auto) quelque chose de malformé. On change une note non-normative en texte normatif pour donner un peu plus de tonus à cette position. Les changements apportés vont aider à réaliser plusieurs déductions raisonnables qui n'étaient pas officiellement permises par le passé, tout en empêchant de passer un X<short> en paramètre à une fonction qui souhaite un X<int> par exemple.

3070: Trivial assignment can skip member subobjects

Jens Maurer démontre que le problème signalé pour l'affectation touche aussi les constructeurs de copie, ce qui est embêtant. On examine une reformulation des règles décrivant la trivialité de ces deux fonctions spéciales. On est satisfaits. Tentatively Ready.

[class] remove redundant "constexpr-suitable" references to determine constexpr-ness of constructors/destructors #8108

C'est un changement éditorial qui change constexpr-suitable pour le rendre presque inopérant, outre dans le cas des coroutines. En gros, presque tout est désormais constexpr-suitable. On vient de frapper un changement majeur!

3067: Array-to-pointer conversion with object type mismatch

L'exemple motivateur est :

int a[5];
int *p1 = &a[0];        // points to the first element of a
auto pa = reinterpret_cast<int(*)[5]>(p1);
int *p2 = *pa;          // valid array-to-pointer conversion?

Selon la personne ayant soulevé ce point, la dernière ligne devrait être UB. On examine la résolution proposée, on la modifie un peu pour clarifier le propos. Tentatively Ready.

3065: Reachability and completeness of types

Ceci est subtil (on parle de nommage de tableaux de dimension inconnue). On va attendre le retour de Davis Herring pour en discuter. On constate que toutes les implémentations traitent le cas suivant de la même manière :

int a[3];
void f() {
  extern int a[];
  // "a" has type "array of unknown bound" in all implementations
}

3064: Mishandling of placement-new in lifetime rules

Il semble que nos règles actuelles traitent mal ce cas de Placement New :

int a;
int *p = &a;
*p = 1;       // #1
new (p) int;

Avec le texte actuel, l'affectation #1 est UB parce que l'objet pointé par p plus bas n'existe pas encore, ce qui est absurde. Ça peut attendre, alors priorité 2.

3062: Overlapping specification of default template arguments

On semble avoir une sorte de double définition d'un terme ici. On travaille une trentaine de minutes et on trouve une solution. On y reviendra.

3060: Change in behavior for noexcept main

Supposons cette étrange idée :

int main() noexcept {}

C'était permis avant que noexcept ne fasse partie du type d'une fonction, mais ce ne l'est plus désormais. Oups! On examine des options pour « moderniser » la description de main() en permettant noexcept d'y apparaître de manière optionnelle. Ça nous va, Tentatively Ready.

3059: throw; in constant expressions

Quelle horreur :

int main() {
  try {
    throw 0;
  } catch (...) {
    constexpr int x = [] {
    try {
      throw;          // #1 // <-- à la compilation!
    } catch (...) {
      return 1;
    } ();
   }
 }

On pense l'interdire, mais on va se donner le temps d'y réfléchir un peu...

3057. Ranking of derived-to-base conversions should ignore reference binding

Nos règles sont suspectes car elles semblent tenir compte de la présence (ou pas) de références dans le processus.

(je dois m'absenter un peu)

À mon retour, Davis Herring discute d'un enjeu de Name Lookup dans le contexte de Core Issue 3065. Il fait entre autres remarquer que pour un tableau de limites inconnues, une réflexion sur l'objet suivi d'une splice sur le résultat nous donne des types différents avec decltype du fait que le splice résultant en révèle les limites! Ça choque les gens présents. Il montre l'exemple suivant :

int a[3];
constexpr auto r=^^a;
void f() {
  extern int a[];
  static_assert(std::is_same_v<decltype(a),decltype([:r:])>);  // ??
  static_assert(std::is_same_v<decltype(a),decltype([:^^a:])>);  // ??
}

En effet, c'est déstabilisant, mais toutes les implémentations font la même chose. Il nous révèle qu'il y a d'autres cas comme celui-ci (il mentionne les paramètres par défaut d'une fonction) qui donnent des résultats impactés par le contexte.

On découvre qu'en C, dans cet exemple, la déclaration locale de a est traitée comme un tableau de taille... connue, en C, avec gcc, clang, msvc et icc. Ouch! Tout le monde est surpris (sauf la personne qui nous en a informé!). Par exemple, https://godbolt.org/z/4r5b7Eobx

La principale raison pour laquelle C++ supporte ce cas est la compatiblité avec C, alors on est un peu subjugués. On convient que dans ce cas, mieux vaut voir le type complet de partout, et déterminer qu'il ne s'agit pas d'un enjeu de réflexivité.

On examine ensuite la contrepartie, soit un tableau local dans une fonction avec une dimension connue mais qui est exposé à l'externe en tant que tableau de dimension inconnue.

On jongle avec l'idée de ne pas permettre de faire une réflexion sur une déclaration extern locale à un bloc. C'est un changement de design, cela dit, et ça nous rend nerveux. L'alternative semble être de produire des informations incorrectes (parfois) par réflexivité. Oh la la... Il va falloir informer EWG, et ça va brasser!

Davis Herring signale qu'il faut faire attention de ne pas bannir les classes locales, qui sont assez communes (https://godbolt.org/z/zeP6c5c8j) :

auto f(int n) {
   struct X {
      int m;
      int f() const { return m + 1; }
   };
   return X { n };
}
int main() {
   return decltype(f(0)){ 3 }.f(); // 4
}

(je vais devoir manquer la deuxième partie de la journée car j'enseigne ce soir, mais c'est pas chic car c'est vraiment un dossier surprenant et intéressant!)

Jour 3 – 6 novembre 2025

Je pensais manquer la première moitié de la journée car il y a une rencontre de la commission des études, dont je suis vice-président, au Collège cet après-midi (matin à Kona), mais un surprise est survenue à la maison et j'ai dû rester chez moi alors je passerai mon temps dans le monde virtuel encore aujourd'hui.

Il y a eu beaucoup de travaux accomplis en mon absence hier. Je note en particulier une étude de P3726 où on a beaucoup parlé de inplace_vector<T> et d'un Placement New constexpr. Les opinions étaient partagées; j'ai hâte d'en savoir plus!

On commence par une Library Issue qui recoupe un Core Issue

US 76 [util.smartptr.shared.create] shared pointer to an array of size 0

Ceci recoupe 4451. make_shared should not refer to a type U[N] for runtime N chez LWG. On a du texte à réviser à ce sujet, alors on fait un survol. Ça semble satisfaisant.

Core Issue 3062: Overlapping specification of default template arguments

On l'a vu hier mais il y a eu de petits changements depuis. Le texte demande de ne pas donner de valeur par défaut à un Pack variadique. Ça semble bien.

Core Issue 3116: First element in an array

Cette Core Issue est née hier d'un commentaire de Walter Brown. Merveilleux! On s'assure d'avoir bien traité le cas à zéro éléments, et c'est Tentatively Ready!

Core Issue 3117: Overriding by a consteval virtual function

C'est une relaxation des règles pour permettre l'implémentation de std::exception::meta.

Core Issue 3065: Reachability and completeness of types

Jens Maurer suggère qu'on envoie ceci devant EWG étant donné l'interaction constatée hier entre les déclarations extern locales à un bloc et la réflexivité soit bien comprise par toutes et tous, et qu'elle soit bien circonscrite. On travaille sur la formulation de la question qu'on compte leur soumettre. Hubert Tong fait remarquer que les annotations (attributes) sur des blocs sont dans le même bateau que les tableaux de taille indéfinie. Il ajoute https://godbolt.org/z/18a1KTs83 à titre d'exemple supplémentaire.

On soumet deux cas d'exemples à EWG, soit ceci :

int a[];
int g();
void f() {
  extern int a[3];
  [[nodiscard]] int g();
}
// "a" has type "array of unknown bound" here
void h() {
  g();  // no warning about discarding the return value
}

... et cela :

int a[3];
[[nodiscard]] int g();

void f() {
  extern int a[];
  // "::a" is still complete here, but
  // is "a" complete here?
  static_assert(sizeof(::a) > 0);
  int g();
  g();  // warning about discarding the return value?
}

Davis Herring va le présenter à EWG pour nous. À suivre...

Core Issue 2875: Missing support for round-tripping null pointer values through indirection/address operators

L'idée est de documenter des différences de comportement entre C et C++ dans l'annexe C du standard :

void f() {
  char *p = nullptr;
  char *p2 = &*p;   // well-defined in C, undefined behavior in C++
  char *p3 = &p[0]; // well-defined in C, undefined behavior in C++
  int a[5];
  int *q = &a[5];   // well-defined in C, undefined behavior in C++
}

Le texte proposé nous convient. Ready, et ce sera un DR.

Core Issue 2923: Note about infinite loops and execution steps

On enlève un paragraphe qui n'est plus pertinent.

Core Issue 2941: Lifetime extension for function-style cast to reference type

Exemple intéressant :

int glob;
struct A {
  constexpr ~A() { p = &glob; }
  int *p;
};
constexpr int f() {
  typedef const A &AR;
  const A &ref = AR{0};
  delete ref.p;
  return 0;
}
extern constexpr int x = f(); // okay

Ouf. Mais le texte convient, et on va de l'avant avec ceci.

Core Issue 3032: Template argument disambiguation

On a une ambiguïté grammaticale :

void g();

template <typename T>
  struct A {
    static void f() {
      g<T::TT>((A *)0);
    }
  };

template <typename T> void g(void *);
template <auto> void g(void *);
template <template <typename> class> void g(void *);

struct Expr { enum { TT = 0 }; };
struct Type { using TT = int; };
struct Tmpl { template <typename> struct TT; };
void h() {
  A<Expr>::f(); // all accept
  A<Type>::f(); // EDG, MSVC accept; GCC, Clang rejects
  A<Tmpl>::f(); // EDG, MSVC accept; GCC, Clang rejects
}

On examine les changements proposés à la grammaire, qui passent par l'introduction de la production template-argument-name. On a plusieurs règles (que je ne connaissais pas!) qui dénotent des endroits où le mot clé template n'est pas permis.

On a cet autre exemple très près de l'abomination :

void g();

template <typename T>
  struct A {
    static void f() {
      g<A>((A *)0);     // all accept
      g<A>((A *)0, 0);  // Clang, GCC, EDG accept; MSVC rejects
    }
};

template <typename T> void g(void *);
template <template <typename> class> void g(void *, int);

void h() { A<int>::f(); }

Brrrr...

(pause du matin)

Les changements à la grammaire semblent satisfaire le groupe. Ce sera un DR.

Core Issue 3033: Scope after declarator-id before determining correspondence

L'exemple motivateur est :

namespace N {
  inline namespace A {
    constexpr int f(int *);
  }
  inline namespace B {
    constexpr int f(long *);
  }
} // namespace N

template <typename T> struct Q { using type = long; };

constexpr int N::f(Q<struct X *>::type *) { return 42; } // #1

namespace N {
  inline namespace B {
    struct X {};
  }
} // namespace N
template <> struct Q<N::B::X *>; // explicit specialization after implicit instantiation
static_assert(N::B::f(0) == 42);

Le texte pour résoudre celle-là n'est pas prêt. On y reviendra.

Core Issue 3043: Lifetime extension for temporaries in expansion statements

On revient sur celle-ci avec une proposition terminologique. Ce qu'on a semble bon, alors on ira de l'avant avec cela. Ce ne sera pas un DR car c'est un tout nouveau mécanisme.

3053. Allowing #undef likely

Oh boy. Les règles permettent

#define likely(x) x
#define unlikely(a, b) a + b

... mais ne permettent pas :

#undef likely
#undef unlikely

On ajoute cette permission.

Core Issue 3063: Lifetime extension of temporaries past function return

On est coincés avec ceci :

struct B { ~B(); };
struct A { const B &b; };
A foo() { return {{}}; }   // #1 crée une temporaire dont la durée de vie est étendue
void bar();
int main() {
  A a = foo();
  bar();
}

La durée de vie de la référence est étendue dû à un ordre inadéquat de règles à appliquer. On ajuste cet ordre car c'est vraiment pas chouette à implémenter pour les compilateurs (c'est probablement impossible à implémenter, en fait). Le changement convient au groupe. Ready.

Core Issue 3082: Allow for call-compatible function types in reinterpret_cast

 Ceci vient d'un NB Comment américain qui demande d'ajouter un cas (raisonnable) pour lequel reinterpret_cast est valide, soit celui des call-compatible functions.

Core Issue 3083: Remove redundant restrictions on class and enum definitions

Un interdit de déclarer une class ou un union dans une for-range-declaration semble redondant. On épure.

Core Issue 3084: compound-statements inside iteration-statements

Le texte existant laissant entendre comme possible quelque chose qui ne l'était pas. On rature.

Core Issue 3085: Apply restriction inside for-range-declaration

Autre petit ajustement mineur du même ordre. On travaille toutefois sur la clarté du nouveau libellé, qui semble sujet à interprétation.

(je dois quitter pour la fin de l'avant-midi hawaïen)

P2785 – Emitting messages at compile-time

On discute de ceci dû à GB 06 qui demande qu'on le supporte. EWG en a parlé et nous a envoyé une demande formelle (ce matin!) de l'inclure pour C++26. On se questionne (en théorie, C++26 est Feature-Complete à ce stade). Plusieurs sont ambivalents : cette proposition a été vue par CWG (une fois) et aux yeux des membres du groupe, plusieurs enjeux de conception semblaient devoir être éclaircis.

P3795 – Miscellaneous Reflection Cleanup

On souhaiterait travailler là-dessus mais l'auteur est chez EWG pour discuter... de réflexivité!

Core Issue 2900, Core Issue 2917

Les débats se poursuivent. (je fais le souper des enfants alors je suis les débats « en diagonale »).

Core Issue 2929: Lifetime of trivially-destructible static or thread-local objects

On est Ok avec la résolution proposée. Ce sera un DR

Core Issue 3001: Inconsistent restrictions for static_cast on pointers to out-of-lifetime objects

Le texte préexistant était incohérent. On procède, ce sera un DR.

Core Issue 3002: Template parameter/argument confusion

Le texte n'est pas tout à fait clair. On corrige. Ce sera un DR.

Core Issue 3004: Pointer arithmetic on array of unknown bound

Exemple amusant :

extern const int arr[];
constexpr const int *p = arr + N;  // #1
constexpr int arr[2] = {0, 1};     // #2
constexpr int k = *p;              // #3

Que faire? « Accept for N == 0 and otherwise #1 is non-constant (clang)? Always accept #1, but reject #3 for out-of-bounds accesses (gcc)? Always accept #1, but always reject #3, even for in-bound accesses (EDG)? Reject #2 (MSVC)? ». La résolution proposée donne un sens clair à l'arithmétique de pointeurs dans ce cas.

Core Issue 3005: Function parameters should never be name-independent

Le texte du standard est incohérent. On a un correctif simple, mais ce ne sera pas un DR (trop novateur)

Core Issue 3008: Missing Annex C entry for void object declarations

Il faut noter quelque part que C permet ce qui suit mais C++ ne le permet pas. C'est un DR.

èxtern void x;

Core Issue 3011: Parenthesized aggregate initialization for new-expressions

On parle ici d'un effort pour uniformiser {} et () lors d'initialisations. C'est un DR.

P2785 – Emitting messages at compile-time

 On réexamine ceci. On se demande quel est le chemin à suivre : procéder en plénière (et dire non)? Laisser EWG le porter pour vote? On discute avec notre Convener pour examiner les options. C'est... politique. Je ne peux pas vous rapporter ce dont nous avons discuté mais c'était complexe, c'était passionant, et ça a duré plus d'une heure.

(pause d'après-midi)

Core Issue 3044: Iterating expansion statements woes

Des problèmes intéressants surviennent de par nos règles de réécriture : elles utilisent static constexpr auto iter = begin + i; où le type de i n'est pas spécifié, or la résolution de + dépend du type de i. De plus, la réécriture inclut for (auto i = begin ; i != end ; ++i, ++result); ce qui pourrait être corrompu par une surcharge de l'opérateur ,. Enfin, le recours à static est malformé.

On a des leviers de réécriture, et on accepte une formule qui évite ces écueils. Tentatively Ready

Cpre Issue 3045: Regularizing environment interactions of expansion statement

Ceci est valide :

template for (auto x : whatever) {
  int x = 42;
}

... mais ceci ne l'est pas :

for (auto g : whatever) {
  int g = 42;
}

Bon... On a une solution, mais c'est pas un DR.

Core Issue 3048: Empty destructuring expansion statements

Ceci est malformé dû à une réécriture qui repose sur un Structured Binding :

struct S { };
void f() {
  S s;
  template for (auto x : s) { }
}

Le texte proposé semble bien.

Core Issue 3054: Use of default arguments depending on shape of postfix-expression in a function call

L'exemple motivateur est amusant :

void f(int = 0) {}

void g() {
  f();          // accepted by all
  (&f)();       // accepted by EDG and clang, rejected by GCC and MSVC
  (*f)();       // accepted by EDG and MSVC, rejected by GCC and clang 
  (0, f)();     // accepted by EDG, rejected by MSVC, GCC and clang
  static_cast<void(&)(int)>(f)();  // accepted by MSVC, rejected by EDG, GCC, and clang
  static_cast<void(*)(int)>(f)();  // rejected by all

  auto p = f;
  p();          // rejected by all
}

On a peut-être une solution...

Core Issue 3057: Ranking of derived-to-base conversions should ignore reference binding

(je dois arrêter, il faut que je dorme un peu; il reste 40 minutes à la journée)

Jour 4 – 7 novembre 2025

Dernière journée avant les votes. Je suis curieux de voir si les tensions politiques d'hier se poursuivront aujourd'hui. Les gens sur place discutent des risques de voir leur vol de retour annulé (nous sommes en période de « fermeture du gouvernement » aux États-Unis).

Jens Maurer explique qu'on va essayer de traiter un maximum de Core Issues avant la pause du matin, car on s'attend à recevoir des propositions rattachées à des NB Comments par la suite et les traiter sera urgent.

Core Issue 3118: Mangling reflections of annotations is infeasible

On a ceci :

[[=1]] void f();
constexpr auto R = annotations_of(^^f)[0];

template <std::meta::info> struct TCls {};

Normalement, les annotations ne sont pas un irritant ici, mais dans un module ça pourrait être exporté... On fait un changement pour que les annotations soient TU-Local (Translation Unit-Local)

Core Issue 3058. "Program point" is not defined

C'est bête quand un texte comme celui du standard ne définit pas un terme dont il se sert, et le terme Program Point semble être semi-défini (ou partiellement défini... à plusieurs endroits). Hubert Tong signale que Davis Herring a écrit une longue missive à ce sujet, alors on va attendre de l'avoir lu avant de l'avoir traité.

On regarde ensuite un changement très léger au texte d'introduction du standard, qui dit ce qu'est C++. On parle des deux premieres paragraphes de [intro.scope]

Core Issue 3077: Undesirable formation of import directive with string-literal

L'exemple motivateur est :

#define STR(X) #X
const char *str = STR(
import u8"hello";     // #1
);

Dans le standard actuel, la ligne #1 est reconnue comme une directive import, or à l'usage ce code est IFNDR. On apporte un changement à [cpp.pre] pour rendre ceci illégal. Le préprocesseur n'a pas l'intelligence requise pour ce genre d'acrobatie. Ce sera un DR.

Core Issue 3079: Allow empty-declarations in anonymous unions

On l'a vu plus tôt cette semaine. Ceci est raisonnable mais interdit :

struct A { union {int x;;} u; };    // OK
struct B { union {int y;;}; };      // error

On fait l'ajout qui permet cela désormais. De toute manière, les compilateurs existants l'acceptent.

3080. Clarify kinds of permitted template template arguments

On parle d'un enjeu terminologique très abstrait : « A template-argument for a template template parameter shall be the name of a template. For a type-tt-parameter, the name shall denote a class template or , alias template, or type template template parameter. For a variable-tt-parameter, the name shall denote a variable template or variable template template parameter. For a concept-tt-parameter, the name shall denote a concept or concept template parameter. ... » Les gras sont les ajouts.

Core Issue 3101: Types "compounded" from other types

On essaie de remplacer une phrase un peu creuse par une énumération qui se veut exhaustive. On semble à l'aise. Ready, pas un DR car on parle de types consteval-only.

Core Issue 3102: Update list of void contexts

Même principe, on a une liste non-exhaustive, mais dans une note non-normative. Ceci sera un DR. On travaille un peu sur une tournure de phrase avec un « ou » qui peut être pris de manière exclusive ou inclusive (ce serait embêtant si on devait générer de la confusion)

Core Issue 3105: Consteval destructor through immediate escalation

On l'a examinée plus tôt cette semaine et on demeure à l'aise. Ready, et ce sera un DR

Core Issue 3106: Redundant exclusion of (non-existent) UCNs in r-char-sequences

Il ne peut pas y avoir de telles séquences dans le Lexer, alors on en enlève la mention. Ready, DR.

Core Issue 3107: Misleading note "An alias template name is never deduced."

On l'a examinée plus tôt cette semaine et on demeure à l'aise. Ready, et ce sera un DR

Core Issue 3108: Reflection on type aliases

Petite clarification. On l'a examinée plus tôt cette semaine et on demeure à l'aise. Ready

Core Issue 3109: Access checking when designating a protected member by a splice

On parle d'une règle à désactiver dans le cas des Splice Expressions. On l'a examinée plus tôt cette semaine et on demeure à l'aise. Ready

Core Issue 3110: Constexpr allocation for literal types

On l'a examinée plus tôt cette semaine et on demeure à l'aise; ça enlève une règle limitant ceci aux types littéraux qui n'est pas particulièrement pertinente dans ce cas. Ready

Core Issue 3111: Template parameter objects of array type

On l'a examinée plus tôt cette semaine. Hubert Tong remarque que le caractère distinct des objets examinés n'est pas clairement établi dans le texte. On fait des retouches et on demande à LWG de le regarder à nouveau juste au cas. Ready (sous réserve de l'approbation de LWG) et ce sera un DR.

Truc amusant : LWG nous envoie un truc à examiner presque au même moment!

Core Issue 3114: Indirect base classes for class member access with direct base class relationship

La question soulevée est à savoir si une ambiguous base class d'un type donné inclut ce type. Hubert Tong pense que non. On réorganise le texte légèrement. On craint une « lecture hostile » d'un passage et on ajoute des mots pour en réduire le risque. Ça faite une solide demie heure de boulot.

On a un accord de LWG pour Core Issue 3111.

Core Issue 3115: Function parameters of consteval-only type

On l'a examinée plus tôt cette semaine. L'intention est de clarifier les propriétés de ces types. Ready.

US 126-189

C'est une modification à [meta.reflection.define.aggregate] faite par LWG. On l'examine. C'est une précision sur le comportement de define_aggregate(). On discute des liens avec les types incomplets. Il semble y avoir un problème avec l'ordre des étapes.

(pause du matin)

P2785 – Emitting messages at compile-time

Jens Maurer demande qui est d'avis qu'il ne faudrait pas traiter ce document aujourd'hui. Une majorité préfère qu'on ne le traite pas. C'est tellement rare qu'on vote chez CWG, c'est déstabilisant!

On migre chez EWG pour suivre le dossier.

Jens Maurer explique la situation. Comme toujours, il est très clair. Shafik Yaghmour explique aussi très clairement l'enjeu pour un implémenteur de mettre en place un mécanisme si nouveau sans avoir un le temps d'y réfléchir. Jonathan Caves mentionne sa préoccupation sur le plan procédural.

Daveed Vandevoorde admet que c'est un nouveau mécanisme, mais pense que l'on en a besoin pour éviter une multiplication de mécanismes par compilateur. Il souligne que c'est un NB Comment. Quelqu'un d'autre dit avoir voté pour mais comprend le problème et dit qu'il serait à l'aise de voter contre maintenant qu'il comprend les enjeux procéduraux. Ville Voutilainen parle d'un besoin criant, mais demande si CWG est en bloc contre cette adoption dans l'immédiat. Puisque c'est un « oui », il est à l'aise avec l'idée d'attendre pour C++29.

Hubert Tong parle du caractère novateur d'admettre des effets de bord à la compilation car cela expose des mécanismes et pratiques internes du compilateur, un truc qu'on préfère éviter. Selon lui, c'est presque aussi révolutionnaire que define_aggregate() mais ça n'a pas eu le même niveau d'analyse. Davis Herring décrit l'impact important d'un tel mécanisme sur l'observabilité des constructeurs et des destructeurs constexpr (il est convaincant : ce qu'il décrit est terrifiant). Quelqu'un de Clang relate l'expérience vécue en implémentant define_aggregate() et dit que ses collègues et lui trouvent encore cela terrifiant. Il espère qu'il y aura au moins un fanion « experimental » sur un tel mécanisme. Shafik Yaghmour revient sur l'importance du processus, que les présentateurs soient convaincants ou populaires ou pas.

Quelqu'un d'EWG parle de divergences d'implémentation (les gens de Clang étaient inconfortables, ceux de EDG l'étaient moins), de craintes d'en arriver à quelque chose de suboptimal, mais il se dit d'avis que la proposition a bel et bien suivi le processus, il ne lui manquait que le Wording. Il parle de gens blessés. John Spicer dit que selon lui, on ne parle pas de sentiments, mais bien de l'introduction de mécanisme novateurs à travers un NB Comment. John Spicer pense que CWG va avoir besoin de temps pour bien traiter cette proposition, et que si le mécanisme est souhaitable, il peut attendre à C++29.

Barry Revzin pense que define_aggregate() est radicalement différent car ses effets de bord sont visibles dans le code source. Il se dit un peu heurté d'un sous-entendu selon lequel il n'aurait pas suivi le processus, relatant le chemin parcouru et les consultations associées à cette proposition. Ville Voutilainen rappelle que le Convener accepte de nouveaux mécanismes s'ils accroissent le consensus, mais constate qu'il n'est pas clair que ce soit le cas ici. Ville Voutilainen dit avoir parlé aux implémenteurs de GCC et avoir entendu des préoccupations sur le nombre d'affichages à produire en fonction du contexte (il y a les contextes manifestly constant evaluated, mais il y a des cas de constant folding et bien d'autres manoeuvres qui sont du ressort du as-if). Il pense que ça serait chouette d'avoir avec C++26 mais que ce n'est pas absolument nécessaire.

(j'ai manqué la fin et le vote car je devais régler une urgence familiale; à mon retour on vote sur US 38 et il n'y a pas consensus; ensuite, on vote sur US 32 pour les allocations non-transitoires pour std::vector et std::string en lien avec P3554, mais je les laisse discuter et je retourne à CWG qui regarde Library Issue 4434 qui semble Ok, puis Library Issue 4435 qui est un ajustement aux règles de has_identifier())

D3920 – Wording for NB comment resolution on trivial relocation

Louis Dionne explique que les mots pour trivial relocation soient retirés de C++26 le temps de réfléchir un peu plus et de revenir avec C++29. Cette proposition est un « Undo » des changements apportés pour intégrer ce mécanisme, mais en conservant les améliorations de type « drive by » qui ont été faites en cours de traitement. C'est une proposition inhabituelle, mais dans les circonstances c'est la chose à faire.

Hubert Tong rappelle que les Core Issues en lien avec ce mécanisme peuvent être rejetées dans les circonstances. On marque ceci Ready.

(pause dîner; je prends une minute pour aller voir le résultat du vote chez EWG et ils ont accepté notre perspective, alors ce sera un mécanisme utile et pertinent, mais pour C++29 ce qui nous permettra de l'étudier convenablement)

(quand ça recommence, je n'ai que l'image car je fais le souper des enfants. On discute de P3795)

P3795 – Miscellaneous Reflection Cleanup

À mon arrivée, on regarde parameters_of(). L'enjeu semble être le traitement des annotations. Je ne note pas tout car c'est une proposition vaste et qu'il y a plusieurs détails qui méritent une attention plus particulière. On identifie un aspect qui semble (légèrement) incohérent mais qui demande un retour à EWG pour connaître leur intention.

Brian Bi demande si tout le monde est d'accord sur le fait que les noms des paramètres n'est pas quelque chose que les compilateurs oublient une fois un changement de bloc réalisé.

(il y a un peu de chaos par la suite car Jens Maurer doit quitter et nous ne connaissons pas ses plans, alors nous explorons les Core Issues qui nous semblent traitables dans les circonstances)

Core Issue 2676: Replacing a complete object having base subobjects

Le texte actuel va trop loin et bloque ceci :

struct A { int n; };
struct B : A {};
B b;
new (&b) B { {5} };  // New A base class does not transparently replace existing A base class due to /8.4.
int k = b.n;  // UB: member n of A base class is outside its lifetime

... de même que :

struct A {
  int n;
  char c;
  // tail padding
};
struct B {
  [[no_unique_address]] A a;
  char in_tail_padding[3];
};

B b;
void f() {
  // Transparently replaces old member, potentially overwriting the data in the tail padding!
  new (&b.a) A{};
}

Le nouveau texte semble préférable au texte préexistant. Ready

P3868 – Allow #line before module declarations

L'exemple motivateur est :

#line 1 "A.cppm"
export module a;

... ce qui est un irritant pour de nombreux outils. On procède, Ready.

(on discute ensuite informellement d'une demande de refactorisation un peu inhabituelle de la grammaire du préprocesseur, demandée à la fois à WG14 et WG21)

P3684 – Fix erroneous behaviour termination semantics for C++26

C'est intéressant. Le changement proposé est de modifier comment les « trappes » associées au Erroneous Behavior nous pètent au visage. Le texte d'origine aurait pu mener à une branche prise qui soit « empoisonnée » par l'existence d'une valeur erronnée dans une branche non-prise. On travaille presque une heure trente sur les nuances entre valeurs erronnées, comportement erronné et diverses variantes.

(pause de l'après-midi)

On se bat encore une heure trente sur le sens de l'affectation, et sur la distinction entre examiner les bits et examiner l'adresse d'une valeur erronée. Les nuances entre la pratique (ce que font les implémentations, ou ce qu'elles peuvent faire) et ce qui est spécifié de manière normative sont discutées en détail. On se questionne aussi sur l'impact de lever une exception faite d'une valeur erronée

Ok, ça s'en va pour vote demain

Core Issue 3100: Destruction order for objects with static storage duration

On a un enjeu d'ordre de destruction d'objets en mémoire static. Ci-dessous, les éléments de a sont détruits, puis dt, puis les deux objets BTemp :

struct DTemp { ~DTemp(); };
struct Temp {
  ~Temp() {
  static DTemp dt;
  }
};
struct BTemp {
  ~BTemp();
};
struct A {
  const BTemp &tb;
  ~A();
};
A a[] = { (Temp(), BTemp()), BTemp() };

int main() {}

On passe pas mal de temps là-dessus.

Core Issue 3088: Clarify macro treatment of identifiers with special meaning

Les auteurs de la proposition sur la relocalisation triviale souhaitent que les termes replaceable_if_eligible or trivially_relocatable_if_eligible demeurent réservés au sens de cette proposition. Le problème est que les nouveaux identifiants ne peuvent briser le code préexistant.

On passe beaucoup de temps là-dessus, et... on ne trouve pas de solution générale à court terme.

(je dois quitter à dix minutes de la fin)

Jour 5 – 8 novembre 2025

Après quelques irritants audio, John Spicer nous accueille.

Rapports des groupes d'études

SG1: Concurrency and Parallelism Study Group : quatre jours de rencontre, traitement de NB Comments et travaux sur les Senders / Receivers, les atomiques, le Forward Progress et la synchronisation. On félicite Eric Niebler pour sa transparence (c'est lui qui a identifié et rapporté les bogues de son oeuvre!), On a aussi fait des travaux en vue de C++29.

SG2: Modules Study Group : inactif cette semaine

SG3: File System Study Group : inactif cette semaine

SG4: Networking Study Group : inactif cette semaine

SG5: Transactional Memory : inactif cette semaine

SG6: Numerics : un jour et demie de rencontre. Travaux sur les entiers et sur les nombrs à virgule flottante, plusieurs propositions relayées à LEWG. On va peut-être avoir char_conv() constexpr!

SG7: Reflection : inactif cette semaine

SG8: Concepts : inactif cette semaine

SG9: Ranges : travaux sur des NB Comments touchant aux Ranges, et quelques propositions envoyées à LEWG. Il se pourrait qu'on ait une version Ranges des algorithmes de <numeric>

SG10: Feature Test : inactif cette semaine

SG12: Undefined and Unspecified Behavior : inactif cette semaine

SG13: I/O : inactif cette semaine

SG14: Low Latency : inactif cette semaine, mais on travaille chaque mois sur la proposition de Patrice Roy et sur les exceptions pour systèmes embarqués

SG15: Tooling : quelques travaux cette semaine

SG16: Unicode : inactif cette semaine mais on progresse

SG17: EWG Incubator : inactif cette semaine

SG18: LEWG Incubator : inactif cette semaine

SG19: Machine Learning : pas de rencontre cette semaine mais on se rencontre souvent. Les LLM sont à l'horizon, et il en va de même pour la formation de larges ensembles en vue de l'entraînement des IA.

SG20: Education : inactif cette semaine

SG21: Contracts : inactif cette semaine

SG22: C/C++ Liason : inactif cette semaine

SG23: Safety and Security : on a discuté des contraintes implicites, des erreurs de pointeurs (séparer le statique du dynamique)

ABI Group : inactif cette semaine

Admin Group : 184 participant(e)s cette semaine, dont un peu plus de 80 en personne

Rapports des groupes de travail

EWG : grosse semaine. Deux jours pleins sur les contrats. Tous les NB Comments sauf deux ont été rejetés, et ces deux ont été traités par CWG. On aura pre! qui imposera la sémantique enforce sur les contrats. Une demi journée sur la Trivial Relocatability, qui a fini par être retirée pour le moment. On a approuvé les annotations sur les paramètres de fonctions, l'ajout d'un trait is_structural_type, on a enlevé constexpr sur certains mécanismes en lien avec les exceptions, et beaucoup d'autres choses chouettes.

LEWG : travaux conjoints avec SG1 sur les Senders / Receivers. On garde std::hive et on le rend constexpr pour C++29. On aura std::format() constexpr, un support dans la bibliothèque pour les Expansion Statements, par de relocabilité pour le moment, inplace_vector ne sera pas Allocator-Aware, des travaux sur SIMD et std::meta::*, etc.

CWG : on a traité beaucoup de NB Comments, dont 33 sont sujets à vote aujourd'hui. Il y a eu neuf rejets et quelques duplicats. On note en particulier Core Issue 1670 à propos de operator auto qui serait Ill-Formed ce qui peut être controversé alors je suis ouvert à séparer le vote en deux et la demande de séparations m'a été livrée tardivement

LWG : ont travaillé extrêmement fort toute la semaine, traitant plus de 100 LWG Issues et plusieurs NB Comments.

Votes proposés par CWG

Les votes amenés par CWG cette semaine sont les suivants.

1. Accept as Defect Reports and apply the proposed resolutions of all issues except issues 1670, 2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, 3082, 3084, 3089, 3092, 3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, 3114, 3115, 3117, and 3118 in P3921R0 (Core Language Working Group "ready" Issues for the November, 2025 meeting) to the C++ Working Paper.

Unanime

2.Apply the proposed resolutions of issues 2917, 2923, 3005, 3043, 3044, 3045, 3048, 3053, 3061, 3063, 3074, 3082, 3084, 3089, 3092, 3093, 3094, 3095, 3098, 3099, 3101, 3108, 3109, 3110, 3113, 3114, 3115, 3117, and 3118 in P3921R0 (Core Language Working Group "ready" Issues for the November, 2025 meeting) to the C++ Working Paper

Unanime

2b. Accept as Defect Reports and apply the proposed resolutions of issue 1670 in P3921R0 (Core Language Working Group "ready" Issues for the November, 2025 meeting) to the C++ Working Paper.

Quelqu'un signale que ceci brise des exemples de code ailleurs dans le standard qui deviendront Ill-Formed ([class.conf.sct]#8), ce qui entraînera un NB Comment. On signale que ce n'est pas une première. On indique que les paragraphes accompagnant les exemples deviennent incorrectes aussi.

On vote. Consensus pour

3a. Postpone vote 3b to the UK meeting in March 2026, and relitigate P3920R0 in an LEWG/EWG joint session at that meeting.

Il y a opposition sur le principe même de tenir ce vote. Il y a aussi beaucoup de confusion sur l'intérêt de tenir les deux votes que sont 3a et 3b.

On vote. Consensus contre

3b. Apply the changes in P3920R0 (Wording for NB comment resolution on trivial relocation) to the C++ Working Paper. This addresses numerous ballot comments (see paper).

On vote. Consensus pour

4. Accept as a Defect Report and apply the changes in P3868R1 (Allow #line before module declarations) to the C++ Working Paper. This addresses ballot comment US 55-102.

Unanime

5. Apply the changes in P3684R1 (Fix erroneous behaviour termination semantics for C++26) to the C++ Working Paper. This addresses ballot comment GB 02-036.

On vote. Consensus pour

Votes proposés par LWG

Les votes amenés par LWG cette semaine sont les suivants.

1. Apply the changes in P3905R0 (C++ Standard Library Ready Issues to be moved in Kona, Nov. 2025) to the C++ working paper.

Unanime

2. Apply the changes in P3906R0 (C++ Standard Library Immediate Issues to be moved in Kona, Nov. 2025) to the C++ working paper.

Unanime

3. Apply the changes in P3016R6 (Resolve inconsistencies in begin/end for valarray and braced initializer lists) to the C++ working paper.

Unanime

4. Apply the changes in P3567R2 (flat_meow fixes) to the C++ working paper.

Unanime

5. Apply the changes in P3663R3 (Future-proof submdspan_mapping) to the C++ working paper. This addresses ballot comments US 66-117 and PL 009.

Unanime

6. Apply the changes in P3914R0 (Assorted NB comment resolutions for Kona 2025) to the C++ working paper. This addresses ballot comments US 160-260, US 209-332, US 228-348, US 263-396, US 265-398, US 266-399, US 112-172, and US 130-193.

Unanime

7. Apply the changes in P3836R2 (Make optional trivially copyable) to the C++ working paper. This addresses ballot comment US 134-215.

Unanime

8. Apply the changes in P3860R1 (Proposed Resolution for NB Comment GB13-309 atomic_ref< T > is not convertible to atomic_ref< const T >) to the C++ working paper, as a Defect Report for C++20. This addresses ballot comment GB13-309.

Unanime

9. Apply the changes in P3388R3 (When Do You Know connect Doesn’t Throw?) to the C++ working paper.

Unanime

10. Apply the changes in P3774R1 (Rename std::nontype, and make it broadly useful) to the C++ working paper. This addresses ballot comments FR-021-218 and FR-019-210.

On vote. Consensus pour

11. Apply the changes in P3819R0 (Remove evaluation_exception() from contract-violation handling for C++26) to the C++ working paper. This addresses ballot comments NL, US 69-125, GB 04-124.

Unanime

12. Apply the changes in P3612R1 (Harmonize proxy-reference operations (LWG 3638 and 4187)) to the C++ working paper.

Unanime

13. Apply the changes in P3778R0 (Fix for type_order template definition) to the C++ working paper.

Unanime

14. Apply the changes in P1789R3 (Library Support for Expansion Statements) to the C++ working paper. This addresses ballot comments NC IT-002, FR 007-011-142, CZ 2-143, US 78-144.

Unanime

Note : ceci montre diverses manières par lesquelles la programmation en C++ a radicalement changé récemment. Fiou!

15. Apply the changes in P3922R1 (Missing deduction guide from simd::mask to simd::vec) to the C++ working paper. This addresses ballot comment DE-287.

Unanime

Note : une application chouette des guides de déduction!

16. Apply the changes in P3815R1 (Add scope_association concept to P3149) to the C++ working paper. This addresses ballot comments CA-393 and FI-392.

Unanime

17. Apply the changes in P3878R1 (Standard library hardening should not use the 'observe' semantic) to the C++ working paper. This addresses ballot comments RU-016, FR-001-014, FR-010-113, US 3-015, and US 61-112.

Unanime (je m'attendais à plus de controverse, mais tant mieux!)

18. Apply the changes in P3887R1 (Make when_all a Ronseal Algorithm) to the C++ working paper.

Unanime

(brève pause café à ce stade)

19. Apply the changes in P3923R0 (Additional NB comment resolutions for Kona 2025) to the C++ working paper. AT 7-213, US 140-233, US 141-235, US 145-234, US 147-240, US 164-203, US 126-189, US 227-346, US 229-347, US 221-339, and US 225-341

Unanime

20. Apply the changes in P3371R5 (Fix C++26 by making the rank-1, rank-2, rank-k, and rank-2k updates consistent with the BLAS) to the C++ working paper. This addresses ballot comment US 168-277.

Unanime

21. Apply the changes in P3391R2 (constexpr std::format) to the C++ working paper. This addresses ballot comment FR 028-271 and US 167-270.

Vote. Consensus pour

22. Apply the changes in P3913R1 (Optimize for std::optional in range adaptors) to the C++ working paper. This addresses ballot comment PL-011.

Unanime

Votes proposés par WG21

Il n'y en a pas cette fois.

Autres rapports

Direction group : une rencontre s'est tenue. Nous avons porté attention aux nombreuses controverses et aux échanges plus « chauds » de la semaine. Nous révisons P2000 en vue d'un renouvellement de la direction générale du langage en vue de C++29, et nous consulterons les Chairs avant publication. Nous poserons un regard plus spécifiquement sur les enjeux d'écosystème de notre langage.

Walter Brown sert un bel hommage à Herb Sutter, qui prend sa retraite en tant que Convener... après 25 ans. D'autres hommages suivent. Bravo! Guy Davidson prend la parole en tant que Convener pour la première fois. Herb Sutter rend un hommage à John Spicer et rappelle que c'est lui, le premier, qui a noté il y a longtemps que export pour les templates, c'était casse-gueule.

On gère ensuite la logistique de fin de rencontre, la présentation de la rencontre de Croydon (UK) en février 2026 Ide même qu'un aperçu des rencontres jusqu'à 2028, presque toutes hors des États-Unis pour des raisons évidentes), et on ferme les livres pour cette rencontre.


Valid XHTML 1.0 Transitional

CSS Valide !