1. US NB comment 10
The new identifiers with special meaning
and
are embarrassingly verbose. They are too long for practical use.
They will not see use in industry because their semantics do not match the semantics requested by over a dozen industry veterans representing seven major projects (Amadeus, Blender, Boost, Parlay, Folly, Qt, HPX) across [P3233], [P3236], [P1144R13], [P3780], etc.
Compiler vendors will have to add a
or
anyway,
to permit their library vendor to optimize types like
in pre-C++26 modes.
Library vendors cannot use the new identifiers with special meaning outside of C++26 mode.
Even in C++26 mode, a compiler-specific "opt-in" (P1144-style) attribute or keyword
may be needed in order to support constexpr
and
,
for which the P2786-style warrant is insufficient.
The new identifiers as such are useful only for user-defined resource-management classes, in C++26-only codebases. (Rule-of-Zero classes do not need them. C++23 codebases must use a vendor-specific mechanism such as an attribute.) This is a very small fraction of a small fraction: permitting this syntax gains very little in performance, but loses much in confusion to the industry and embarrassment to the Committee.
For all these reasons these identifiers should be removed from C++26, and their design reconsidered for C++29 after there has been any implementation and usage experience. We can safely remove these identifiers with special meaning, without at all harming the library feature of "relocation" itself.
2. Important note
We needn’t touch the library clauses; we needn’t touch the traits; literally nothing in the Standard depends on these embarrassing and inutile keywords. (In fact, as US NB comment 9 points out, nothing in the Standard depends on the notion of "replaceability" either.)
3. Proposed wording
The wording in this section is relative to the Committee Draft of C++26, [N5013].
3.1. [class.pre]
Modify [class.pre] as follows:
class-property-specifier:
final
trivially_relocatable_if_eligible
replaceable_if_eligible [...]
5․ Each class-property-specifier shall appear at most once within a single class-property-specifier-seq. Whenever a class-key is followed by a class-head-name, the identifier
,
final and a colon or left brace, the identifier is interpreted as a class-property-specifier., or
trivially_relocatable_if_eligible ,
replaceable_if_eligible [Example:
—end example]struct A ; struct A final {}; // OK, definition of struct A, // not value-initialization of variable final
struct X { struct C { constexpr operator int () { return 5 ; } }; struct B trivially_relocatable_if_eligible final : C {}; // OK, definition of nested class B, // not declaration of a bit-field member // trivially_relocatable_if_eligible final };
3.2. [class.prop]
Modify [class.prop] as follows:
1․ A trivially copyable class is a class:
that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([special], [class.copy.ctor], [class.copy.assign]),
where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
that has a trivial, non-deleted destructor ([class.dtor]).
2․ A class
is default-movable if
C
overload resolution for direct-initializing an object of type
from an xvalue of type
C selects a constructor that is a direct member of
C and is neither user-provided nor deleted,
C overload resolution for assigning to an lvalue of type
from an xvalue of type
C selects an assignment operator function that is a direct member of
C and is neither user-provided nor deleted, and
C
has a destructor that is neither user-provided nor deleted.
C 3․ A class is eligible for trivial relocation unless it
has any virtual base classes,
has a base class that is not a trivially relocatable class,
has a non-static data member of an object type that is not of a trivially relocatable type, or
has a deleted destructor,
except that it is implementation-defined whether an otherwise-eligible union having one or more subobjects of polymorphic class type is eligible for trivial relocation.
4․ A class
is a trivially relocatable class if it is eligible for trivial relocation and
C
has theclass-property-specifier,
trivially_relocatable_if_eligible is a union with no user-declared special member functions, or
is default-movable.
5․ [Note: A class with const-qualified or reference non-static data members can be trivially relocatable. —end note]
6․ A class
is eligible for replacement unless
C
it has a base class that is not a replaceable class,
it has a non-static data member that is not of a replaceable type,
overload resolution fails or selects a deleted constructor when direct-initializing an object of type
from an xvalue of type
C ([dcl.init.general]),
C overload resolution fails or selects a deleted assignment operator function when assigning to an lvalue of type
from an xvalue of type
C ([expr.assign], [over.assign])), or
C it has a deleted destructor.
7․ A class
is a replaceable class if it is eligible for replacement and
C
has theclass-property-specifier,
replaceable_if_eligible is a union with no user-declared special member functions, or
is default-movable.
8․ [Note: Accessibility of the special member functions is not considered when establishing trivial relocatability or replaceability. —end note]
9․ [Note: Not all trivially copyable classes are trivially relocatable or replaceable. —end note]
10․ A class
is a standard-layout class if it: [...]
S
3.3. [diff.cpp23.dcl.dcl]
Modify [diff.cpp23.dcl.dcl] as follows:
1. Affected subclause: [dcl.decl.general]
Change: Introduction ofand
trivially_relocatable_if_eligible as identifiers with special meaning.
replaceable_if_eligible
Rationale: Support declaration of trivially relocatable and replaceable types.
Effect on original feature: Valid C++ 2023 code can become ill-formed.
[Example:struct C {}; struct C replaceable_if_eligible {}; // was well-formed (new variable replaceable_if_eligible) // now ill-formed (redefines C) —end example]
3.4. [diff.cpp23.library]
Note: This clause should point to [cpp.replace.general], not [res.on.macro.definitions]; that is the subject of US NB comment 57.
Modify [diff.cpp23.library] as follows:
2. Affected subclause: [res.on.macro.definitions]
Change: Additional restrictions on macro names.
Rationale: Avoid hard to diagnose or non-portable constructs.
Effect on original feature: Names of special identifiers may not be used as macro names. Valid C++ 2023 code that definesor
replaceable_if_eligible as macros is invalid in this revision of C++.
trivially_relocatable_if_eligible
3.5. [lex.name]
Modify [lex.name] as follows:
2. The identifiers in Table 4 have a special meaning when appearing in a certain context. When referred to in the grammar, these identifiers are used explicitly rather than using the identifier grammar production. Unless otherwise specified, any ambiguity as to whether a given identifier has a special meaning is resolved to interpret the token as a regular identifier.
Table 4 — Identifiers with special meaning
final import post replaceable_if_eligible override module pre trivially_relocatable_if_eligible