Annex C (informative) Compatibility [diff]

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

C.1.1 General [diff.cpp20.general]

Subclause [diff.cpp20] lists the differences between C++ and ISO C++ 2020 (ISO/IEC 14882:2020, Programming Languages — C++), by the chapters of this document.

C.1.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]
Change: Concatenated string-literals can no longer have conflicting encoding-prefixes.

Rationale: Removal of unimplemented conditionally-supported feature.

Effect on original feature: Concatenation of string-literals with different encoding-prefixes is now ill-formed.
For example: auto c = L"a" U"b"; // was conditionally-supported; now ill-formed

C.1.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.
For example: decltype(auto) f(int&& x) { return (x); } // returns int&&; previously returned int& int& g(int&& x) { return x; } // ill-formed; previously well-formed
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.
For example: arr[1, 2] // was equivalent to arr[(1, 2)], // now equivalent to arr.operator[](1, 2) or ill-formed

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

Affected subclause: [dcl.init.string]
Change: UTF-8 string literals may initialize arrays of char or unsigned char.

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

Effect on original feature: Arrays of char or unsigned char may 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.
For example: struct A { char8_t s[10]; }; struct B { char s[10]; }; void f(A); void f(B); int main() { f({u8""}); // ambiguous }

C.1.5 [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++.
For example: template<bool> struct A { }; template<bool B> void f(void (*)(A<B>) noexcept(B)); void g(A<false>) noexcept; void h() { f(g); // ill-formed; previously well-formed }

C.1.6 [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: <expected>, <stdatomic.h>, <spanstream>, and <stacktrace>.
Valid C++ 2020 code that #includes headers with these names may be invalid in this revision of C++.

C.1.7 [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_­with with 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_­with may fail to compile in this revision of C++.
For example: template<class T, class U> requires equality_­comparable_­with<T, U> bool attempted_equals(const T&, const U& u); // previously selected overload 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); // ambiguous overload; previously // rejected by partial ordering bool test(shared_ptr<int> p) { return attempted_equals(p, nullptr); // ill-formed; previously well-formed }

C.1.8 [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 or format_­args_­t may become ill-formed.
For example: auto s = std::format("{:d}", "I am not a number"); // ill-formed, // previously threw format_­error
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.
For example: struct tiny { int bit: 1; }; auto t = tiny(); std::format("{}", t.bit); // ill-formed, previously returned "0"

C.1.9 [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 S that is a specialization of basic_­string may change meaning in this revision of C++.
For example: std::string s1 = "some long string that forces allocation", s2 = s1; std::move(s1).substr(10, 5); assert(s1 == s2); // unspecified, previously guaranteed to be true std::string s3(std::move(s2), 10, 5); assert(s1 == s2); // unspecified, previously guaranteed to be true

C.1.10 [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++.
For example: struct B { auto operator<=>(const B&) const = default; }; struct D : private B { void f(std::set<B, std::less<>>& s) { s.erase(*this); // ill formed; previously well-formed } };