De uitslag van de C++26 DIS-stemming
C++26 is gezakt voor de DIS-stemming (Draft International Standard). Voor zover ik weet, is dit het eerste C++-concept dat een stemming niet overleeft. Robert Seacord, de convenor van het C-comité, schreef dat hij niet denkt dat een standaard uit SC22 ooit eerder een stemming is niet gepasseerd. Daveed Vandevoorde, lid van de WG21 Direction Group (P5000R1), merkte op dat geen enkel eerder C++-concept zelfs maar één stem tegen heeft gekregen.
Dit betekent dat reflectie, std::execution, library hardening en contracts zich allemaal bevinden in een concept dat ISO niet heeft goedgekeurd. Hoe lang de vertraging zal zijn, is op dit moment nog onbekend.
De stemming sloot op 23 oktober 2026. Robert Seacord plaatste de volgende resultaten op LinkedIn op de volgende dag:
Balloting has completed for C++26. Unfortunately it was Disapproved.
Mijn standpunt
Ik heb deze serie neutraal gehouden zolang de stemming openstond, omdat ik niemand naar een bepaalde kant wilde duwen. Nu de stemming voorbij is, kan ik zeggen waar ik sta.
Ik ben een groot voorstander van contracts als idee en ik mis ze sindsdien ze zijn verwijderd uit C++20. Vanwege mijn focus op API-ontwerp, bibliotheken, goede interfaces en frameworks — redenen waarom ik ook in LEWG zit — waardeer ik contracts zeer. Controle is één belangrijk voordeel: het programma kan zijn eigen aannames verifiëren.
De tweede pijler, die ik net zo belangrijk vind, is documentatie. Een preconditie of postconditie in de signatuur legt de intentie van de API-ontwerper vast. Hierdoor weten gebruikers wat ze kunnen verwachten en hoe ze de functie moeten gebruiken, en documentatiesystemen zoals Doxygen of cppreference.com kunnen dit direct tonen. Een commentaar kan hetzelfde zeggen, maar er is niets dat garandeert dat het commentaar correct blijft; het kan ongemerkt afwijken van de code.
Een contract is onderdeel van de code. De compiler controleert het samen met de functie, en wanneer de controles zijn ingeschakeld, leidt een schending tot een duidelijke fout. Hierdoor kan de documentatie niet stilzwijgend verouderen. Concepts bieden ons dit al voor de typen die een functie accepteert (op compile-time). Contracts zijn het ontbrekende deel dat hetzelfde doet voor waarden op run-time. Ik zou contracts graag in de standaard zien en het is jammer dat ze het deze keer niet hebben gehaald. Mijn voorkeur is om ze te behouden, maar als het ontwerp hierdoor uiteindelijk beter wordt, is dat ook een goed resultaat.
Dit is voor mij geen abstracte vraag; ik ben al begonnen met het doceren van C++26 contracts in mijn workshops, en mp-units maakt gebruik van de C++26-versie.
De cijfers
In deel 2 van deze serie werd uitgelegd aan welke twee voorwaarden een DIS moet voldoen. Het concept is op beide punten tekortgeschoten:
| Voorwaarde | Vereiste | Resultaat |
|---|---|---|
| Stemmen voor, van de stemgerechtigde (P-)leden | Minimaal twee derde | 12 van de 20 (60%) |
| Negatieve stemmen, van alle stemmende organen | Maximaal 25% | 9 van de 22 (41%) |
Voor twee derde van de 20 stemmen waren 14 stemmen voor nodig; er waren er 12. Een kwart van de 22 staat maximaal vijf negatieve stemmen toe; er waren er negen. Elk van deze twee punten alleen al zou voldoende zijn om het concept af te keuren.
Herkomst van de cijfers
Deze gegevens komen uit het officiële SC22-stemresultaat. Dit is niet openbaar; alleen nationale afgevaardigden van SC22 kunnen dit inzien op de commissiesite van ISO. Ten tijde van het schrijven stond het resultaat nog niet op de publieke projectpagina van ISO of in een WG21-document. De cijfers zijn echter te controleren in de eerder genoemde publieke post.
Waarom verschilt de telling tussen 8 en 9 "Nee"-stemmen?
Dit komt doordat de twee regels verschillende groepen tellen en geen van beide regels onthoudingen meerekent:
- De eerste regel telt alleen de P-leden die 'Ja' of 'Nee' stemden. De post vermeldt expliciet: P-members who abstained are not counted in this vote. Omdat 12 van de 20 'Ja' stemden, stemden er 8 'Nee'.
- De tweede regel telt elk nationaal orgaan dat 'Ja' of 'Nee' stemde, ongeacht of dit een P-lid is of niet. Er waren er 22, waarvan er 9 'Nee' stemden.
Dit betekent dat 2 van de 22 stemmen afkomstig waren van organen die geen P-leden zijn. Het officiële resultaat laat zien wie dit zijn: Iran (een O-lid, observerend lid) stemde 'Nee', en Nigeria (geregistreerd zonder SC22-status) stemde 'Ja'. Net als elk nationaal orgaan mogen zij stemmen op een DIS, maar tellen ze niet mee voor de eerste regel.
Welke landen stemden en hoe?
Het officiële resultaat noemt elk land. Negen landen stemden 'Nee': Denemarken, Finland, Iran, Italië, Japan, Luxemburg, Roemenië, Spanje en Zweden. Elk van deze landen stuurde commentaren mee bij hun stem. Frankrijk en Ierland onthielden zich van stemming, maar stuurden ook commentaren, wat neerkomt op in totaal 11 landen met commentaren. Polen en de Verenigde Staten onthielden zich van stemming. Ik ben zelf lid van het Poolse nationale orgaan.
De commentaren zelf zijn nog niet beschikbaar. De ISO/IEC-richtlijnen (clausule 2.6.5 van Deel 1) vereisen een volledig rapport binnen 12 weken na afloop van de stemming, inclusief het resultaat, de beslissing van de commissievoorzitter en de volledige tekst van de commentaren. Voor een stemming die sloot op 23 oktober, betekent dit uiterlijk medio januari 2027. In de committee-draft fase publiceerde WG21 een dergelijk rapport als N5028; het is onbekend of ze dit nu opnieuw zullen doen.
De onthouding van Polen
De positie van Polen over C++ wordt bepaald in een technisch comité van het Pools Comité voor Standaardisatie, KT 331. De stemming daar ging over de vraag of Polen de DIS moest afwijzen en technische commentaren naar ISO moest sturen. Dit voorstel is niet aangenomen, waardoor Polen "Onthouding" aan ISO heeft doorgegeven en er geen technische commentaren konden worden toegevoegd.
Ik zal de exacte uitslag niet delen of zeggen wie hoe heeft gestemd, aangezien dit een interne stemming is.
Het had bijna kunnen gebeuren dat er helemaal geen positie was vanwege een ander probleem. Een paar dagen voordat de Poolse stemming sloot, misten we nog stemmen voor een quorum. Zonder quorum zou er geen Poolse positie zijn geweest. Sommige mensen op de lijst waren van baan gewisseld; ik probeerde de stille leden te bereiken via e-mail en LinkedIn, maar sommige e-mails kwamen terug omdat de adressen waarschijnlijk van voormalige werkgevers waren.
Ongeacht hoe je denkt dat C++26 had moeten verlopen, volgen hieruit twee lessen:
- Als je in een nationaal comité zit: stem. De stem telt, ongeacht de richting.
- Als je niet langer kunt deelnemen: vraag om verwijderd te worden van de lijst met stemgerechtigde leden. Het quorum telt je mee, dus een inactief lid maakt het voor iedereen moeilijker om een quorum te bereiken. Het commissiebureau kan niet zomaar iemand verwijderen die stil is geworden; dat moet het lid zelf aangeven.
Waar gingen de 'Nee'-stemmen over?
Ik ben ervan overtuigd dat de 'Nee'-stemmen over contracts gingen. Daar lag voor de stemming al de oppositie. Beide bezwaren die tijdens de plenaire zitting in Croydon werden uitgelegd (die C++26 naar de stemming stuurde), gingen over contracts. Diverse nationale commentaren op het committee-draft vroegen om ze te verwijderen. P4238R1 vroeg nationale organen om 'Nee' te stemmen vanwege het ontwerp van de contracts en de manier waarop dit door het comité was gevoerd. Ik verwacht dat alle negen 'Nee'-stemmen over contracts gaan, maar dat weten we pas zeker als de commentaren worden gepubliceerd.
Voor lezers die de serie niet hebben gevolgd: dit is de feature (uitgelegd in detail in deel 1):
#include <cmath>
double checked_sqrt(double x)
pre (x >= 0.0)
post (r : r >= 0.0)
{
const double root = std::sqrt(x);
contract_assert(!std::isnan(root));
return root;
}
Deze code bepaalt niet of elke controle wordt uitgevoerd of wat er gebeurt als er een controle faalt. Het concept definieert vier evaluatie-semantieken: ignore, observe, enforce en quick-enforce, en laat de keuze daartussen over aan de implementatie. In GCC 16 kies je er een via een compiler-flag. Een groot deel van het geschil gaat over deze keuze: is een contract-assertie een controle die de build kan weglaten, of is het een garantie waar het programma op kan vertrouwen (zie deel 3). Deel 4 en 5 behandelen de rest.
Wat gebeurt er nu?
De richtlijnen bieden vier mogelijke acties na een mislukte DIS: 1 Het verspreiden van een herziend 'enquiry draft', met een stemming van acht weken in plaats van twaalf. 2 Het verspreiden van een herziend 'committee draft' voor commentaren. 3 Het verspreiden als een 'draft technical specification'. 4 Het project annuleren.
De SC22-voorzitter kiest een van de eerste drie opties, in samenwerking met het SC22-secretariaat en de WG21-convenor, en in overleg met het ISO/IEC-centraalkantoor. Alleen annuleren moet door SC22 als geheel worden beslist. De rol van WG21 is om de commentaren te behandelen, een koers aan te bevelen en, indien nodig, een herzien concept voor te bereiden. Toen ik dit schreef, was er nog geen aankondiging over welke keuze is gemaakt.
Waarschuwing: Geen van deze routes heeft nog een officiële datum. De richtlijnen bepalen alleen de termijn voor de stemming van acht weken over een herzien enquiry draft, en die stemming kan pas beginnen als er een herzien concept is. P4238R1 schat de vertraging in maanden in, niet in jaren. P4433R0, geschreven door zestien voorstanders van contracts vóórdat het resultaat bekend was, stelt dat dit "niet realistisch" is, omdat het verwijderen van contracts op zichzelf een grote wijziging aan het concept zou zijn en de specificatie van library hardening opnieuw ontworpen zou moeten worden.
De volgende WG21-vergadering vindt plaats in Búzios, Brazilië, van 16 tot 21 november 2026. Dit zal de eerste vergadering van het volledige comité zijn sinds het resultaat, en de meningen over de te volgen koers zijn verdeeld:
- Sommigen willen dat WG21 opnieuw een stemming aanvraagt zonder contracts te wijzigen of te verwijderen. P4433R0 is een formeel voorstel hiervoor. Er wordt ook gevraagd om commentaren die verwijdering eisen af te wijzen, tenzij ze nieuwe technische informatie aanleveren.
- Anderen zeggen dat de kortetermijnoplossing simpel is. J. Daniel Garcia, een van de auteurs van P4238R1, schreef: "the short term solution is simple, remove one problematic feature and the rest of the standard can very likely be approved". Vandevoorde's aanbeveling zal zijn om contracts uit het concept te verwijderen, met aanpassingen om library hardening te behouden.
- Sommige eerdere nationale commentaren vroegen om een technische specificatie of een white paper in plaats van een volledige standaard.
Ik zou graag een plan zien in Búzios, en het is voor mij niet voldoende als dit alleen zegt wat er met contracts moet gebeuren. Als ze C++26 moeten verlaten zodat de rest kan worden gepubliceerd, is dat jammer, maar ik kan daarmee leven. Ik zou echter niet willen dat alles andere met hen moet wachten; ik wil dat de rest van C++26 zo snel mogelijk wordt uitgebracht.
Een moeilijkere vraag is hoe het ontwerp vanaf hier verbetert. De bezwaren die ik heb gelezen wijzen in verschillende richtingen: sterkere garanties die door de compiler worden gecontroleerd, meer van het ontwerp in de library, eerst een technische specificatie, of controles die niet kunnen worden uitgeschakeld. Ik heb nog geen enkel alternatief gezien dat door alle tegenstanders zou worden geaccepteerd, dus het is moeilijk te zeggen welke wijziging iedereen tevreden zou stellen.
Zal het nog steeds C++26 heten?
Hierover is nog geen besluit genomen. C++23 werd zo laat gepubliceerd dat het ISO/IEC 14882:2024 is, maar niemand noemt het C++24. Vandevoorde twijfelt of het definitieve concept in 2026 gestemd kan worden en schreef dat als dit in 2027 gebeurt, "C++27 zinvol zou zijn". Totdat een nieuwe editie is gepubliceerd, is de huidige C++ standaard nog steeds ISO/IEC 14882:2024 (C++23).
Wat betekent dit voor je code van vandaag?
Compilers implementeren features uit het working draft, en de stemming verandert niets aan wat ze al leveren. GCC 16 accepteert -std=c++26 en Clang heeft -std=c++2c. GCC 16 implementeert contracts als onderdeel van zijn experimentele C++26-ondersteuning; de Clang-implementatie is nog niet gemerged. Of vendors elke drafted feature onder die flag behouden, is aan henzelf; niemand kan dat vandaag beloven.
Als je team al C++26-features gebruikt of deze leert, hoeft er nu nog niets ongedaan gemaakt te worden. Echter, wat je compiler vandaag implementeert is een concept, en het kan afwijken van de uiteindelijk gepubliceerde standaard.
Tip: Als je code al pre, post of contract_assert gebruikt met GCC 16, leun je op een experimentele implementatie van het deel van het concept waarover het geschil gaat.
Wat staat er nog open?
- De tekst van de commentaren van de 11 landen die deze hebben gestuurd.
- Wat WG21 in Búzios aanbeveelt, welke koers er wordt gekozen en op welke planning.
Ik hoop dat compilers C++26 contracts blijven implementeren, ongeacht wat het comité besluit. Eén bezwaar is het gebrek aan ervaring in productie en deployment (zie deel 5 voor beide kanten van dat argument). Deze ervaring is moeilijk op te doen zonder implementaties die mensen kunnen gebruiken; het is een kip-en-ei probleem. Ik zou liever niet zien dat hetzelfde bezwaar terugkomt de volgende keer dat er over contracts wordt gestemd.
Groetjes,