Files
2025-10-25 03:02:53 +03:00

453 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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*]