Annex C (informative) Compatibility [diff] (original) (raw)

C.2 C++ and ISO C++ 2020 [diff.cpp20]

C.2.1 General [diff.cpp20.general]

Subclause [diff.cpp20] lists the differences between C++ and ISO C++ 2020, in addition to those listed above, by the chapters of this document.

C.2.2 [lex]: lexical conventions [diff.cpp20.lex]

Affected subclause: [lex.name]

Change: Previously valid identifiers containing characters not present in UAX #44 properties XID_Start or XID_Continue, or not in Normalization Form C, are now rejected.

Rationale: Prevent confusing characters in identifiers.

Requiring normalization of names ensures consistent linker behavior.

Effect on original feature: Some identifiers are no longer well-formed.

Affected subclause: [lex.string]

Rationale: Removal of unimplemented conditionally-supported feature.

[Example 1: auto c = L"a" U"b"; — _end example_]

C.2.3 [expr]: expressions [diff.cpp20.expr]

Affected subclause: [expr.prim.id.unqual]

Change: Change move-eligible id-expressions from lvalues to xvalues.

Rationale: Simplify the rules for implicit move.

Effect on original feature: Valid C++ 2020 code that relies on a returned id-expression's being an lvalue may change behavior or fail to compile.

[Example 1: decltype(auto) f(int&& x) { return (x); } int& g(int&& x) { return x; } — _end example_]

Affected subclause: [expr.sub]

Change: Change the meaning of comma in subscript expressions.

Rationale: Enable repurposing a deprecated syntax to support multidimensional indexing.

Effect on original feature: Valid C++ 2020 code that uses a comma expression within a subscript expression may fail to compile.

[Example 2: arr[1, 2] — _end example_]

C.2.4 [stmt]: statements [diff.cpp20.stmt]

Affected subclause: [stmt.ranged]

Rationale: Improve usability of the range-based for statement.

Effect on original feature: Destructors of some temporary objects are invoked later.

[Example 1: void f() { std::vector<int> v = { 42, 17, 13 }; std::mutex m;for (int x : static_cast<void>(std::lock_guardstd::mutex\(m)), v) { std::lock_guardstd::mutex\ guard(m); } } — _end example_]

C.2.5 [dcl]: declarations [diff.cpp20.dcl]

Affected subclause: [dcl.init.string]

Change: UTF-8 string literals may initialize arrays of char orunsigned char.

Rationale: Compatibility with previously written code that conformed to previous versions of this document.

Effect on original feature: Arrays of char or unsigned charmay now be initialized with a UTF-8 string literal.

This can affect initialization that includes arrays that are directly initialized within class types, typically aggregates.

[Example 1: struct A { char8_t s[10];};struct B { char s[10];};void f(A);void f(B);int main() { f({u8""}); } — _end example_]

C.2.6 [temp]: templates [diff.cpp20.temp]

Affected subclause: [temp.deduct.type]

Change: Deducing template arguments from exception specifications.

Rationale: Facilitate generic handling of throwing and non-throwing functions.

Effect on original feature: Valid ISO C++ 2020 code may be ill-formed in this revision of C++.

[Example 1: template<bool> struct A { };template<bool B> void f(void (*)(A<B>) noexcept(B));void g(A<false>) noexcept;void h() { f(g); } — _end example_]

C.2.7 [library]: library introduction [diff.cpp20.library]

Affected subclause: [headers]

Change: New headers.

Rationale: New functionality.

Effect on original feature: The following C++ headers are new:,,,,,,,,, and.

Valid C++ 2020 code that #includes headers with these names may be invalid in this revision of C++.

C.2.8 [concepts]: concepts library [diff.cpp20.concepts]

Affected subclauses: [cmp.concept], [concept.equalitycomparable], and [concept.totallyordered]

Change: Replace common_reference_with in three_way_comparable_with,equality_comparable_with, and totally_ordered_withwith an exposition-only concept.

Rationale: Allow uncopyable, but movable, types to model these concepts.

Effect on original feature: Valid C++ 2020 code relying on subsumption with common_reference_withmay fail to compile in this revision of C++.

[Example 1: template<class T, class U> requires equality_comparable_with<T, U> bool attempted_equals(const T&, const U& u); template<class T, class U> requires common_reference_with<const remove_reference_t<T>&, const remove_reference_t<U>&> bool attempted_equals(const T& t, const U& u); bool test(shared_ptr<int> p) { return attempted_equals(p, nullptr); } — _end example_]

C.2.9 [mem]: memory management library [diff.cpp20.memory]

Affected subclause: [allocator.traits.general]

Change: Forbid partial and explicit program-defined specializations of allocator_traits.

Rationale: Allow addition of allocate_at_least to allocator_traits, and potentially other members in the future.

Effect on original feature: Valid C++ 2020 code that partially or explicitly specializes allocator_traitsis ill-formed with no diagnostic required in this revision of C++.

C.2.10 [utilities]: general utilities library [diff.cpp20.utilities]

Affected subclause: [format]

Change: Signature changes: format, format_to, vformat_to,format_to_n, formatted_size.

Removal of format_args_t.

Rationale: Improve safety via compile-time format string checks, avoid unnecessary template instantiations.

Effect on original feature: Valid C++ 2020 code that contained errors in format strings or relied on previous format string signatures orformat_args_t may become ill-formed.

[Example 1: auto s = std::format("{:d}", "I am not a number"); — _end example_]

Affected subclause: [format]

Change: Signature changes: format, format_to, format_to_n,formatted_size.

Rationale: Enable formatting of views that do not support iteration when const-qualified and that are not copyable.

Effect on original feature: Valid C++ 2020 code that passes bit-fields to formatting functions may become ill-formed.

[Example 2: struct tiny { int bit: 1;};auto t = tiny(); std::format("{}", t.bit); — _end example_]

Affected subclause: [format.string.std]

Change: Restrict types of formatting arguments used as width or precision in a std-format-spec.

Rationale: Disallow types that do not have useful or portable semantics as a formatting width or precision.

Effect on original feature: Valid C++ 2020 code that passes a boolean or character type as_arg-id_ becomes invalid.

[Example 3: std::format("{:*^{}}", "", true); std::format("{:*^{}}", "", '1'); — _end example_]

Affected subclause: [format.formatter.spec]

Change: Removed the formatter specialization:template<size_t N> struct formatter<const charT[N], charT>;

Rationale: The specialization is inconsistent with the design of formatter, which is intended to be instantiated only with cv-unqualified object types.

Effect on original feature: Valid C++ 2020 code that instantiated the removed specialization can become ill-formed.

C.2.11 [strings]: strings library [diff.cpp20.strings]

Affected subclause: [string.classes]

Change: Additional rvalue overload for the substr member function and the corresponding constructor.

Rationale: Improve efficiency of operations on rvalues.

Effect on original feature: Valid C++ 2020 code that created a substring by calling substr (or the corresponding constructor) on an xvalue expression with type Sthat is a specialization of basic_stringmay change meaning in this revision of C++.

[Example 1: std::string s1 = "some long string that forces allocation", s2 = s1; std::move(s1).substr(10, 5); assert(s1 == s2); std::string s3(std::move(s2), 10, 5); assert(s1 == s2); — _end example_]

C.2.12 [containers]: containers library [diff.cpp20.containers]

Affected subclauses: [associative.reqmts] and [unord.req]

Change: Heterogeneous extract and erase overloads for associative containers.

Rationale: Improve efficiency of erasing elements from associative containers.

Effect on original feature: Valid C++ 2020 code may fail to compile in this revision of C++.

[Example 1: struct B { auto operator<=>(const B&) const = default;};struct D : private B { void f(std::set<B, std::less<>>& s) { s.erase(*this); } }; — _end example_]

C.2.13 [thread]: concurrency support library [diff.cpp20.thread]

Affected subclause: [thread.barrier]

Change: In this revision of C++, it is implementation-defined whether a barrier's phase completion step runs if no thread calls wait.

Previously the phase completion step was guaranteed to run on the last thread that calls arrive or arrive_and_drop during the phase.

In this revision of C++, it can run on any of the threads that arrived or waited at the barrier during the phase.

Rationale: Correct contradictory wording and improve implementation flexibility for performance.

Effect on original feature: Valid C++ 2020 code using a barrier might have different semantics in this revision of C++ if it depends on a completion function's side effects occurring exactly once, on a specific thread running the phase completion step, or on a completion function's side effects occurring without wait having been called.

[Example 1: auto b0 = std::barrier(1); b0.arrive(); b0.arrive(); int data = 0;auto b1 = std::barrier(1, [&] { data++; }); b1.arrive(); assert(data == 1); b1.arrive(); — _end example_]