Kona removes trivial relocatability from the C++26 draft
The November meeting removes a feature that could not be repaired in time and tightens library hardening. Draft adoption and compiler implementation remain different milestones.
A feature freeze does not guarantee that every adopted feature reaches publication. The November C++ meeting removed trivial relocatability from the C++26 draft after finding a blocking problem the committee did not expect to repair within the remaining schedule. That decision matters to code experimenting with the feature, including code built with a compiler that has already implemented the earlier draft.
Herb Sutter's November 10 Kona report records the removal. The meeting concluded on November 8, but this post uses the report's publication date. Sutter describes strong consensus to remove the feature after identifying a showstopper bug. His report does not supply the technical details of that bug, so it cannot support a claim about precisely which implementation mechanism caused the withdrawal.
The broader meeting was concerned with ballot feedback and repairs after the feature freeze. Contracts remained in the draft, with fixes, and reflection remained part of C++26. The different outcomes illustrate how draft review can retain one major addition while removing another. Neither outcome should be inferred from whether an earlier meeting adopted a paper enthusiastically.
Relocation combines transfer with ending the source lifetime
The withdrawn P2786R13 proposal describes relocation as an operation distinct from ordinary copying. The intended transformation transfers an object's value into destination storage and ends the source object's lifetime. Its utility includes moving container elements without paying for avoidable per-element operations when a type permits a cheaper mechanism.
The proposal provided both low-level and higher-level interfaces. Its bulk trivially_relocate facility targeted contiguous sequences. A higher-level relocate algorithm could use a suitable mechanism for types that were not trivially relocatable as well. This gave library authors an abstraction over the operation while keeping a specialized optimization path available.
The source lifetime is essential. A byte copy that leaves two objects both believing they own the same resource has different semantics from transferring the resource and ending the source lifetime. Destruction behavior must agree with the transfer. The optimization therefore needs language and library rules, not only permission to call a memory-copying function.
I understand the appeal because RAII is the strongest reason I still take C++ seriously for resource-owning abstractions. The ownership model makes destruction meaningful. Any shortcut for transferring those objects has to preserve that meaning, including when the source ceases to be an object whose destructor will later release the resource.
Relocatability and replaceability answer different questions
P2786 also distinguishes trivial relocatability from replaceability. Its discussion of container operations explains why transferring a value into fresh storage is not automatically equivalent to assigning into an existing object. A container optimization can be observable if it substitutes one operation for another without the required property.
The paper consequently supplied separate traits and class-property specifications. The contextual spellings trivially_relocatable_if_eligible and replaceable_if_eligible were chosen to avoid promising a property that the declaration could not establish regardless of its subobjects. Eligibility remained part of the model.
That terminology makes the design tension concrete. A generic container wants to select an efficient implementation from type properties. A type author needs the selected operation to preserve its semantics. One Boolean description of a type can be insufficient when the proposed transformations answer different lifetime and replacement questions.
The proposal's revision history records changes to interfaces and eligibility rules before its initial adoption. Those changes are useful background for understanding how much semantics the feature carries. They do not establish which of those historical questions caused November's blocking problem. The removal report supports the decision, while the earlier paper explains the intended facility.
Compiler support does not guarantee standard status
The Clang 21.1 release notes list implementation of P2786R13. That was a legitimate description of the compiler's August support for the then-current draft. November's standards decision changes the feature's status in C++26 without changing what the earlier compiler release had documented.
This distinction matters for public headers. Source that uses experimental draft syntax can acquire a compiler dependency before the standard is final. A compiler's acceptance establishes implementation support in that version and mode. It cannot guarantee that the committee will preserve the same interface through ballot resolution.
Removal also does not imply that every existing relocation optimization becomes newly invalid. Libraries and compilers may have their own mechanisms and documented extensions. The concrete standards result is narrower. The withdrawn C++26 feature cannot be treated as a portable requirement of the forthcoming standard merely because it was previously adopted.
For maintainers following draft work, proposal revision identifiers help preserve that distinction. P2786R13 identifies what an experiment implemented. The current working draft determines which standardized requirements remain under consideration after Kona. A single label such as C++26 support is too coarse to express both facts.
Hardening receives a different outcome
The meeting also adopted P3878R1, dated November 6, by Ville Voutilainen, Jonathan Wakely, John Spicer, and Stephan T. Lavavej. This paper changes hardened standard library preconditions from checking semantics to terminating semantics. It fixes the possibility that an observed violation could return from the handler and continue into undefined behavior.
The distinction between checking and termination was already present in the contracts framework. Observe checks a condition and can report the violation without stopping normal continuation. For an ordinary configurable assertion, that behavior can be intentional. For a hardened library precondition guarding an invalid operation, the authors argue that it defeats the expected guarantee.
Before the change, the draft explicitly assigned undefined behavior if a non-terminating handler returned after such a violation. P3878 removes that route from a conforming hardened implementation. A vendor can still offer an observed checking mode as an extension, but that mode does not meet the revised definition of a hardened implementation.
This is a substantive difference in what the configuration name promises. A user requesting hardening can depend on the requirement that the violated precondition not simply be observed and followed by execution of the invalid library operation. The facility is still scoped to the designated hardened preconditions, rather than a proof of every library requirement.
The scope of the repair is also important when comparing configurations. A library can report an invalid index during development yet still allow the process to continue under its chosen observation policy. That is useful evidence about a defect, but it does not establish the stronger property expected from a conforming hardened implementation after this change. The revised terminology separates those deployment choices.
The paper does not require a vendor to remove its existing observation mode. It requires the vendor to distinguish that mode from the standard's hardened category. This preserves an incremental diagnostic option while making a stronger configuration name carry a stronger requirement. A build description that merely says assertions are enabled would still be ambiguous about which of these behaviors it requests.
This distinction can be assessed without assuming any particular application or regulatory requirement. A library operation has a documented precondition, and the hardened configuration has a documented response when that condition is false. The fix makes those two pieces agree before the function proceeds with its ordinary effects.
Terminating semantics do not require one universal outcome
P3878 carefully distinguishes terminating semantics from a guarantee that the whole program always terminates. An implementation that permits a replacement violation handler can allow that handler to throw. The exception can prevent entry into the rest of the library function without immediately terminating the program.
That qualification preserves the actual property the fix needs. The invalid operation must not continue after the violated precondition. Both stopping the process and leaving through a supported throwing handler can prevent that continuation. Describing the fix as always aborting would overstate its wording.
The paper says the original hardening authors regard this as a bug fix and that the relevant national-body commenters accept it as resolving their concerns. Those are specific statements about this change. They do not mean every objection to contracts has disappeared, or that the final standard has already completed its remaining review.
I favor this kind of precise correction because it makes the guarantee assessable at the operation being protected. Kona's two outcomes involve different judgments. Trivial relocatability could not be repaired within the schedule according to the meeting report. Library hardening had a concrete correction the committee could adopt, requiring a terminating semantic so a violated designated precondition cannot simply return into the guarded invalid operation.