This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

452
cppdraft/diff/cpp20.md Normal file
View File

@@ -0,0 +1,452 @@
[diff.cpp20]
# Annex C (informative) Compatibility [[diff]](./#diff)
## C.2 C++ and ISO C++ 2020 [diff.cpp20]
### [C.2.1](#general) General [[diff.cpp20.general]](diff.cpp20.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L461)
Subclause [diff.cpp20] lists the differences between C++ and
ISO C++ 2020,
in addition to those listed above,
by the chapters of this document[.](#general-1.sentence-1)
### [C.2.2](#lex) [[lex]](lex "5Lexical conventions"): lexical conventions [[diff.cpp20.lex]](diff.cpp20.lex)
[1](#lex-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L470)
**Affected subclause:** [[lex.name]](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[.](#lex-1.sentence-1)
**Rationale:** Prevent confusing characters in identifiers[.](#lex-1.sentence-2)
Requiring normalization of names ensures consistent linker behavior[.](#lex-1.sentence-3)
**Effect on original feature:** Some identifiers are no longer well-formed[.](#lex-1.sentence-4)
[2](#lex-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L483)
**Affected subclause:** [[lex.string]](lex.string)
**Change:** Concatenated [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* can no longer have
conflicting [*encoding-prefix*](lex.ccon#nt:encoding-prefix "5.13.3Character literals[lex.ccon]")es[.](#lex-2.sentence-1)
**Rationale:** Removal of unimplemented conditionally-supported feature[.](#lex-2.sentence-2)
**Effect on original feature:** Concatenation of [*string-literal*](lex.string#nt:string-literal "5.13.5String literals[lex.string]")*s* with different [*encoding-prefix*](lex.ccon#nt:encoding-prefix "5.13.3Character literals[lex.ccon]")es
is now ill-formed[.](#lex-2.sentence-3)
[*Example [1](#lex-example-1)*: auto c = L"a" U"b"; // was conditionally-supported; now ill-formed — *end example*]
### [C.2.3](#expr) [[expr]](expr "7Expressions"): expressions [[diff.cpp20.expr]](diff.cpp20.expr)
[1](#expr-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L501)
**Affected subclause:** [[expr.prim.id.unqual]](expr.prim.id.unqual)
**Change:** Change move-eligible [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")*s* from lvalues to xvalues[.](#expr-1.sentence-1)
**Rationale:** Simplify the rules for implicit move[.](#expr-1.sentence-2)
**Effect on original feature:** Valid C++ 2020 code that relies on a returned [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]")'s
being an lvalue may change behavior or fail to compile[.](#expr-1.sentence-3)
[*Example [1](#expr-example-1)*: decltype(auto) f(int&& x) { return (x); } // returns int&&; previously returned int&int& g(int&& x) { return x; } // ill-formed; previously well-formed — *end example*]
[2](#expr-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L516)
**Affected subclause:** [[expr.sub]](expr.sub)
**Change:** Change the meaning of comma in subscript expressions[.](#expr-2.sentence-1)
**Rationale:** Enable repurposing a deprecated syntax to support multidimensional indexing[.](#expr-2.sentence-2)
**Effect on original feature:** Valid C++ 2020 code that uses a comma expression within a
subscript expression may fail to compile[.](#expr-2.sentence-3)
[*Example [2](#expr-example-2)*: arr[1, 2] // was equivalent to arr[(1, 2)],// now equivalent to arr.operator[](1, 2) or ill-formed — *end example*]
### [C.2.4](#stmt) [[stmt]](stmt "8Statements"): statements [[diff.cpp20.stmt]](diff.cpp20.stmt)
[1](#stmt-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L533)
**Affected subclause:** [[stmt.ranged]](stmt.ranged)
**Change:** The lifetime of temporary objects in the [*for-range-initializer*](stmt.pre#nt:for-range-initializer "8.1Preamble[stmt.pre]") is extended until the end of the loop ([[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#stmt-1.sentence-1)
**Rationale:** Improve usability of the range-based for statement[.](#stmt-1.sentence-2)
**Effect on original feature:** Destructors of some temporary objects are invoked later[.](#stmt-1.sentence-3)
[*Example [1](#stmt-example-1)*: void f() { std::vector<int> v = { 42, 17, 13 };
std::mutex m; for (int x :static_cast<void>(std::lock_guard<std::mutex>(m)), v) { // lock released in C++ 2020 std::lock_guard<std::mutex> guard(m); // OK in C++ 2020, now deadlocks}} — *end example*]
### [C.2.5](#dcl) [[dcl]](dcl "9Declarations"): declarations [[diff.cpp20.dcl]](diff.cpp20.dcl)
[1](#dcl-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L557)
**Affected subclause:** [[dcl.init.string]](dcl.init.string)
**Change:** UTF-8 string literals may initialize arrays of char orunsigned char[.](#dcl-1.sentence-1)
**Rationale:** Compatibility with previously written code that conformed to previous versions of this document[.](#dcl-1.sentence-2)
**Effect on original feature:** Arrays of char or unsigned char may now be initialized with a UTF-8 string literal[.](#dcl-1.sentence-3)
This can affect initialization that includes arrays
that are directly initialized within class types, typically aggregates[.](#dcl-1.sentence-4)
[*Example [1](#dcl-example-1)*: struct A {char8_t s[10];};struct B {char s[10];};
void f(A);void f(B);
int main() { f({u8""}); // ambiguous} — *end example*]
### [C.2.6](#temp) [[temp]](temp "13Templates"): templates [[diff.cpp20.temp]](diff.cpp20.temp)
[1](#temp-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L588)
**Affected subclause:** [[temp.deduct.type]](temp.deduct.type)
**Change:** Deducing template arguments from exception specifications[.](#temp-1.sentence-1)
**Rationale:** Facilitate generic handling of throwing and non-throwing functions[.](#temp-1.sentence-2)
**Effect on original feature:** Valid ISO C++ 2020 code may be ill-formed in this revision of C++[.](#temp-1.sentence-3)
[*Example [1](#temp-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); // ill-formed; previously well-formed} — *end example*]
### [C.2.7](#library) [[library]](library "16Library introduction"): library introduction [[diff.cpp20.library]](diff.cpp20.library)
[1](#library-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L608)
**Affected subclause:** [[headers]](headers)
**Change:** New headers[.](#library-1.sentence-1)
**Rationale:** New functionality[.](#library-1.sentence-2)
**Effect on original feature:** The following C++ headers are new:[<expected>](expected.syn#header:%3cexpected%3e "22.8.2Header <expected> synopsis[expected.syn]"),[<flat_map>](flat.map.syn#header:%3cflat_map%3e "23.6.7Header <flat_­map> synopsis[flat.map.syn]"),[<flat_set>](flat.set.syn#header:%3cflat_set%3e "23.6.10Header <flat_­set> synopsis[flat.set.syn]"),[<generator>](generator.syn#header:%3cgenerator%3e "25.8.2Header <generator> synopsis[generator.syn]"),[<mdspan>](mdspan.syn#header:%3cmdspan%3e "23.7.3.2Header <mdspan> synopsis[mdspan.syn]"),[<print>](print.syn#header:%3cprint%3e "31.7.4Header <print> synopsis[print.syn]"),[<spanstream>](span.streams.overview#header:%3cspanstream%3e "31.9.1Overview[span.streams.overview]"),[<stacktrace>](stacktrace.syn#header:%3cstacktrace%3e "19.6.2Header <stacktrace> synopsis[stacktrace.syn]"),[<stdatomic.h>](stdatomic.h.syn#header:%3cstdatomic.h%3e "32.5.12C compatibility[stdatomic.h.syn]"), and[<stdfloat>](stdfloat.syn#header:%3cstdfloat%3e "17.4.2Header <stdfloat> synopsis[stdfloat.syn]")[.](#library-1.sentence-3)
Valid C++ 2020 code that #includes headers with these names may be
invalid in this revision of C++[.](#library-1.sentence-4)
### [C.2.8](#concepts) [[concepts]](concepts "18Concepts library"): concepts library [[diff.cpp20.concepts]](diff.cpp20.concepts)
[1](#concepts-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L630)
**Affected subclauses:** [[cmp.concept]](cmp.concept), [[concept.equalitycomparable]](concept.equalitycomparable), and [[concept.totallyordered]](concept.totallyordered)
**Change:** Replace common_reference_with in three_way_comparable_with,equality_comparable_with, and totally_ordered_with with an exposition-only concept[.](#concepts-1.sentence-1)
**Rationale:** Allow uncopyable, but movable, types to model these concepts[.](#concepts-1.sentence-2)
**Effect on original feature:** Valid C++ 2020 code relying on subsumption
with common_reference_with may fail to compile in this revision of C++[.](#concepts-1.sentence-3)
[*Example [1](#concepts-example-1)*: template<class T, class U>requires [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, U>bool attempted_equals(const T&, const U& u); // previously selected overloadtemplate<class T, class U>requires [common_reference_with](concept.commonref#concept:common_reference_with "18.4.5Concept common_­reference_­with[concept.commonref]")<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 orderingbool test(shared_ptr<int> p) {return attempted_equals(p, nullptr); // ill-formed; previously well-formed} — *end example*]
### [C.2.9](#memory) [[mem]](mem "20Memory management library"): memory management library [[diff.cpp20.memory]](diff.cpp20.memory)
[1](#memory-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L659)
**Affected subclause:** [[allocator.traits.general]](allocator.traits.general)
**Change:** Forbid partial and explicit program-defined specializations
of allocator_traits[.](#memory-1.sentence-1)
**Rationale:** Allow addition of allocate_at_least to allocator_traits,
and potentially other members in the future[.](#memory-1.sentence-2)
**Effect on original feature:** Valid C++ 2020 code
that partially or explicitly specializes allocator_traits is ill-formed with no diagnostic required in this revision of C++[.](#memory-1.sentence-3)
### [C.2.10](#utilities) [[utilities]](utilities "22General utilities library"): general utilities library [[diff.cpp20.utilities]](diff.cpp20.utilities)
[1](#utilities-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L673)
**Affected subclause:** [[format]](format)
**Change:** Signature changes: format, format_to, vformat_to,format_to_n, formatted_size[.](#utilities-1.sentence-1)
Removal of format_args_t[.](#utilities-1.sentence-2)
**Rationale:** Improve safety via compile-time format string checks,
avoid unnecessary template instantiations[.](#utilities-1.sentence-3)
**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[.](#utilities-1.sentence-4)
[*Example [1](#utilities-example-1)*: auto s = std::format("{:d}", "I am not a number"); // ill-formed,// previously threw format_error — *end example*]
[2](#utilities-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L693)
**Affected subclause:** [[format]](format)
**Change:** Signature changes: format, format_to, format_to_n,formatted_size[.](#utilities-2.sentence-1)
**Rationale:** Enable formatting of views
that do not support iteration when const-qualified and
that are not copyable[.](#utilities-2.sentence-2)
**Effect on original feature:** Valid C++ 2020 code that passes bit-fields to formatting functions
may become ill-formed[.](#utilities-2.sentence-3)
[*Example [2](#utilities-example-2)*: struct tiny {int bit: 1;};
auto t = tiny();
std::format("{}", t.bit); // ill-formed, previously returned "0" — *end example*]
[3](#utilities-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L715)
**Affected subclause:** [[format.string.std]](format.string.std)
**Change:** Restrict types of formatting arguments
used as *width* or *precision* in
a *std-format-spec*[.](#utilities-3.sentence-1)
**Rationale:** Disallow types that do not have useful or portable semantics as
a formatting width or precision[.](#utilities-3.sentence-2)
**Effect on original feature:** Valid C++ 2020 code that passes a boolean or character type as*arg-id* becomes invalid[.](#utilities-3.sentence-3)
[*Example [3](#utilities-example-3)*: std::format("{:*^{}}", "", true); // ill-formed, previously returned "*" std::format("{:*^{}}", "", '1'); // ill-formed, previously returned an// implementation-defined number of '*' characters — *end example*]
[4](#utilities-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L734)
**Affected subclause:** [[format.formatter.spec]](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[.](#utilities-4.sentence-2)
**Effect on original feature:** Valid C++ 2020 code that instantiated the removed specialization
can become ill-formed[.](#utilities-4.sentence-3)
### [C.2.11](#strings) [[strings]](strings "27Strings library"): strings library [[diff.cpp20.strings]](diff.cpp20.strings)
[1](#strings-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L749)
**Affected subclause:** [[string.classes]](string.classes)
**Change:** Additional rvalue overload for the substr member function and
the corresponding constructor[.](#strings-1.sentence-1)
**Rationale:** Improve efficiency of operations on rvalues[.](#strings-1.sentence-2)
**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++[.](#strings-1.sentence-3)
[*Example [1](#strings-example-1)*: 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 — *end example*]
### [C.2.12](#containers) [[containers]](containers "23Containers library"): containers library [[diff.cpp20.containers]](diff.cpp20.containers)
[1](#containers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L773)
**Affected subclauses:** [[associative.reqmts]](associative.reqmts) and [[unord.req]](unord.req)
**Change:** Heterogeneous extract and erase overloads
for associative containers[.](#containers-1.sentence-1)
**Rationale:** Improve efficiency of erasing elements from associative containers[.](#containers-1.sentence-2)
**Effect on original feature:** Valid C++ 2020 code may fail to compile in this revision of C++[.](#containers-1.sentence-3)
[*Example [1](#containers-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); // ill-formed; previously well-formed}}; — *end example*]
### [C.2.13](#thread) [[thread]](thread "32Concurrency support library"): concurrency support library [[diff.cpp20.thread]](diff.cpp20.thread)
[1](#thread-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L797)
**Affected subclause:** [[thread.barrier]](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[.](#thread-1.sentence-1)
Previously the phase completion step was guaranteed to run on the last thread that calls arrive or arrive_and_drop during the phase[.](#thread-1.sentence-2)
In this revision of C++,
it can run on any of the threads that arrived or waited at the barrier
during the phase[.](#thread-1.sentence-3)
**Rationale:** Correct contradictory wording and
improve implementation flexibility for performance[.](#thread-1.sentence-4)
**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[.](#thread-1.sentence-5)
[*Example [1](#thread-example-1)*: auto b0 = std::barrier(1);
b0.arrive();
b0.arrive(); // implementation-defined; previously well-definedint data = 0;auto b1 = std::barrier(1, [&] { data++; });
b1.arrive();
assert(data == 1); // implementation-defined; previously well-defined b1.arrive(); // implementation-defined; previously well-defined — *end example*]