[diff.cpp23] # Annex C (informative) Compatibility [[diff]](./#diff) ## C.1 C++ and ISO C++ 2023 [diff.cpp23] ### [C.1.1](#general) General [[diff.cpp23.general]](diff.cpp23.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L8) Subclause [diff.cpp23] lists the differences between C++ and ISO C++ 2023, by the chapters of this document[.](#general-1.sentence-1) ### [C.1.2](#lex) [[lex]](lex "5 Lexical conventions"): lexical conventions [[diff.cpp23.lex]](diff.cpp23.lex) [1](#lex-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L16) **Affected subclause:** [[lex.operators]](lex.operators) **Change:** New operator ^^[.](#lex-1.sentence-1) **Rationale:** Required for new features[.](#lex-1.sentence-2) **Effect on original feature:** Valid C++ 2023 code that contains two consecutive ^ tokens can be ill-formed in this revision of C++[.](#lex-1.sentence-3) [*Example [1](#lex-example-1)*: struct C { int operator^(int); };int operator^(int (C::*p)(int), C);int i = &C::operator^^C{}; // ill-formed; previously well-formed — *end example*] [2](#lex-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L32) **Affected subclause:** [[lex.key]](lex.key) **Change:** New keywords[.](#lex-2.sentence-1) **Rationale:** Required for new features[.](#lex-2.sentence-2) - [(2.1)](#lex-2.1) The contract_assert keyword is added to introduce a contract assertion through an [*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9 Assertion statement [stmt.contract.assert]") ([[stmt.contract.assert]](stmt.contract.assert "8.9 Assertion statement")). **Effect on original feature:** Valid C++ 2023 code using contract_assert as an identifier is not valid in this revision of C++[.](#lex-2.sentence-3) ### [C.1.3](#expr) [[expr]](expr "7 Expressions"): expressions [[diff.cpp23.expr]](diff.cpp23.expr) [1](#expr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L49) **Affected subclause:** [[expr.arith.conv]](expr.arith.conv) **Change:** Operations mixing a value of an enumeration type and a value of a different enumeration type or of a floating-point type are no longer valid[.](#expr-1.sentence-1) **Rationale:** Reinforcing type safety[.](#expr-1.sentence-2) **Effect on original feature:** A valid C++ 2023 program that performs operations mixing a value of an enumeration type and a value of a different enumeration type or of a floating-point type is ill-formed[.](#expr-1.sentence-3) [*Example [1](#expr-example-1)*: enum E1 { e };enum E2 { f };bool b = e <= 3.7; // ill-formed; previously well-formedint k = f - e; // ill-formed; previously well-formedauto x = true ? e : f; // ill-formed; previously well-formed — *end example*] [2](#expr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L69) **Affected subclauses:** [[expr.rel]](expr.rel) and [[expr.eq]](expr.eq) **Change:** Comparing two objects of array type is no longer valid[.](#expr-2.sentence-1) **Rationale:** The old behavior was confusing since it compared not the contents of the two arrays, but their addresses[.](#expr-2.sentence-2) **Effect on original feature:** A valid C++ 2023 program directly comparing two array objects is rejected as ill-formed in this document[.](#expr-2.sentence-3) [*Example [2](#expr-example-2)*: int arr1[5];int arr2[5];bool same = arr1 == arr2; // ill-formed; previously well-formedbool idem = arr1 == +arr2; // compare addressesbool less = arr1 < +arr2; // compare addresses, unspecified result — *end example*] [3](#expr-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L88) **Affected subclause:** [[expr.delete]](expr.delete) **Change:** Calling delete on a pointer to an incomplete class is ill-formed[.](#expr-3.sentence-1) **Rationale:** Reduce undefined behavior[.](#expr-3.sentence-2) **Effect on original feature:** A valid C++ 2023 program that calls delete on an incomplete class type is ill-formed[.](#expr-3.sentence-3) [*Example [3](#expr-example-3)*: struct S; void f(S *p) {delete p; // ill-formed; previously well-formed}struct S {}; — *end example*] ### [C.1.4](#dcl.dcl) [[dcl]](dcl "9 Declarations"): declarations [[diff.cpp23.dcl.dcl]](diff.cpp23.dcl.dcl) [1](#dcl.dcl-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L110) **Affected subclause:** [[dcl.decl.general]](dcl.decl.general) **Change:** Introduction of trivially_relocatable_if_eligible andreplaceable_if_eligible as identifiers with special meaning ([[lex.name]](lex.name "5.11 Identifiers"))[.](#dcl.dcl-1.sentence-1) **Rationale:** Support declaration of trivially relocatable and replaceable types ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#dcl.dcl-1.sentence-2) **Effect on original feature:** Valid C++ 2023 code can become ill-formed[.](#dcl.dcl-1.sentence-3) [*Example [1](#dcl.dcl-example-1)*: struct C {};struct C replaceable_if_eligible {}; // was well-formed (new variable replaceable_if_eligible)// now ill-formed (redefines C) — *end example*] [2](#dcl.dcl-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L126) **Affected subclause:** [[dcl.init.list]](dcl.init.list) **Change:** Pointer comparisons between initializer_list objects' backing arrays are unspecified[.](#dcl.dcl-2.sentence-1) **Rationale:** Permit the implementation to store backing arrays in static read-only memory[.](#dcl.dcl-2.sentence-2) **Effect on original feature:** Valid C++ 2023 code that relies on the result of pointer comparison between backing arrays may change behavior[.](#dcl.dcl-2.sentence-3) [*Example [2](#dcl.dcl-example-2)*: bool ne(std::initializer_list a, std::initializer_list b) {return a.begin() != b.begin() + 1;}bool b = ne({2,3}, {1,2,3}); // unspecified result; previously false — *end example*] [3](#dcl.dcl-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L145) **Affected subclause:** [[dcl.array]](dcl.array) **Change:** Previously, T...[n] would declare a pack of function parameters[.](#dcl.dcl-3.sentence-1) T...[n] is now a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]")[.](#dcl.dcl-3.sentence-2) **Rationale:** Improve the handling of packs[.](#dcl.dcl-3.sentence-3) **Effect on original feature:** Valid C++ 2023 code that declares a pack of parameters without specifying a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") becomes ill-formed[.](#dcl.dcl-3.sentence-4) [*Example [3](#dcl.dcl-example-3)*: template void f(T... [1]);template void g(T... ptr[1]);int main() { f(nullptr, nullptr); // ill-formed, previously void f(int [1], double [1]) g(nullptr, nullptr); // ok} — *end example*] [4](#dcl.dcl-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L167) **Affected subclause:** [[dcl.attr.grammar]](dcl.attr.grammar) **Change:** New token :][.](#dcl.dcl-4.sentence-1) **Rationale:** Required for new features[.](#dcl.dcl-4.sentence-2) **Effect on original feature:** Valid C++ 2023 code that contained an [*attribute-specifier*](dcl.attr.grammar#nt:attribute-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") with an [*attribute-using-prefix*](dcl.attr.grammar#nt:attribute-using-prefix "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") but no attributes and no whitespace is ill-formed in this revision of C++[.](#dcl.dcl-4.sentence-3) [*Example [4](#dcl.dcl-example-4)*: struct [[using CC:]] C; // ill-formed; previously well-formedstruct [[using DD: ]] D; // OK — *end example*] ### [C.1.5](#temp) [[temp]](temp "13 Templates"): templates [[diff.cpp23.temp]](diff.cpp23.temp) [1](#temp-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L185) **Affected subclause:** [[temp.constr]](temp.constr) **Change:** Some atomic constraints become fold expanded constraints[.](#temp-1.sentence-1) **Rationale:** Permit the subsumption of fold expressions[.](#temp-1.sentence-2) **Effect on original feature:** Valid C++ 2023 code may become ill-formed[.](#temp-1.sentence-3) [*Example [1](#temp-example-1)*: template struct A;struct S {static constexpr int compare(const S&) { return 1; }}; template void f(A *, A *)requires (T::compare(U{}) && ...); // was well-formed (atomic constraint of type bool),// now ill-formed (results in an atomic constraint of type int)void g(A *ap) { f(ap, ap);} — *end example*] [2](#temp-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L209) **Affected subclause:** [[temp.deduct.call]](temp.deduct.call) **Change:** Template argument deduction from overload sets succeeds in more cases[.](#temp-2.sentence-1) **Rationale:** Allow consideration of constraints to disambiguate overload sets used as parameters in function calls[.](#temp-2.sentence-2) **Effect on original feature:** Valid C++ 2023 code may become ill-formed[.](#temp-2.sentence-3) [*Example [2](#temp-example-2)*: template void f(T &&, void (*)(T &&)); void g(int &); // #1inline namespace A {void g(short &&); // #2}inline namespace B {void g(short &&); // #3}void q() {int x; f(x, g); // ill-formed; previously well-formed, deducing T = int&} There is no change to the applicable deduction rules for the individual g candidates: Type deduction from #1 does not succeed; type deductions from #2 and #3 both succeed[.](#temp-2.sentence-4) — *end example*] ### [C.1.6](#library) [[library]](library "16 Library introduction"): library introduction [[diff.cpp23.library]](diff.cpp23.library) [1](#library-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L243) **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:[](contracts.syn#header:%3ccontracts%3e "17.10.1 Header synopsis [contracts.syn]"),[](debugging.syn#header:%3cdebugging%3e "19.7.2 Header synopsis [debugging.syn]"),[](hazard.pointer.syn#header:%3chazard_pointer%3e "32.11.3.2 Header synopsis [hazard.pointer.syn]"),[](hive.syn#header:%3chive%3e "23.3.8 Header synopsis [hive.syn]"),[](inplace.vector.syn#header:%3cinplace_vector%3e "23.3.15 Header synopsis [inplace.vector.syn]"),[](linalg.syn#header:%3clinalg%3e "29.9.2 Header synopsis [linalg.syn]"),[](meta.syn#header:%3cmeta%3e "21.4.1 Header synopsis [meta.syn]"),[](rcu.syn#header:%3crcu%3e "32.11.2.2 Header synopsis [rcu.syn]"),[](simd.syn#header:%3csimd%3e "29.10.3 Header synopsis [simd.syn]"),[](stdbit.h.syn#header:%3cstdbit.h%3e "22.12 Header synopsis [stdbit.h.syn]"),[](stdckdint.h.syn#header:%3cstdckdint.h%3e "29.11.1 Header synopsis [stdckdint.h.syn]"), and[](text.encoding.syn#header:%3ctext_encoding%3e "28.4.1 Header synopsis [text.encoding.syn]")[.](#library-1.sentence-3) Valid C++ 2023 code that #includes headers with these names may be invalid in this revision of C++[.](#library-1.sentence-4) [2](#library-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L265) **Affected subclause:** [[res.on.macro.definitions]](res.on.macro.definitions) **Change:** Additional restrictions on macro names[.](#library-2.sentence-1) **Rationale:** Avoid hard to diagnose or non-portable constructs[.](#library-2.sentence-2) **Effect on original feature:** Names of special identifiers may not be used as macro names[.](#library-2.sentence-3) Valid C++ 2023 code that defines replaceable_if_eligible ortrivially_relocatable_if_eligible as macros is invalid in this revision of C++[.](#library-2.sentence-4) ### [C.1.7](#mem) [[mem]](mem "20 Memory management library"): memory management library [[diff.cpp23.mem]](diff.cpp23.mem) [1](#mem-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L278) **Affected subclause:** [[c.malloc]](c.malloc) **Change:** Calling realloc with a non-null pointer and zero size has erroneous behavior[.](#mem-1.sentence-1) **Rationale:** The C standard library does not define this behavior[.](#mem-1.sentence-2) **Effect on original feature:** Valid C++ 2023 code that calls realloc with a non-null pointer and a size of zero is erroneous and may change behavior[.](#mem-1.sentence-3) ### [C.1.8](#containers) [[containers]](containers "23 Containers library"): containers library [[diff.cpp23.containers]](diff.cpp23.containers) [1](#containers-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L290) **Affected subclause:** [[span.overview]](span.overview) **Change:** span is constructible from initializer_list[.](#containers-1.sentence-1) **Rationale:** Permit passing a braced initializer list to a function taking span[.](#containers-1.sentence-2) **Effect on original feature:** Valid C++ 2023 code that relies on the lack of this constructor may refuse to compile, or change behavior in this revision of C++[.](#containers-1.sentence-3) [*Example [1](#containers-example-1)*: void one(pair); // #1void one(span); // #2void t1() { one({1, 2}); } // ambiguous between #1 and #2; previously called #1void two(span);void t2() { two({{1, 2}}); } // ill-formed; previously well-formedvoid *a[10];int x = span{a, 0}.size(); // x is 2; previously 0 any b[10];int y = span{b, b + 10}.size(); // y is 2; previously 10 — *end example*] ### [C.1.9](#strings) [[strings]](strings "27 Strings library"): strings library [[diff.cpp23.strings]](diff.cpp23.strings) [1](#strings-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L316) **Affected subclause:** [[string.conversions]](string.conversions) **Change:** Output of floating-point overloads of to_string and to_wstring[.](#strings-1.sentence-1) **Rationale:** Prevent loss of information and improve consistency with other formatting facilities[.](#strings-1.sentence-2) **Effect on original feature:** to_string and to_wstring function calls that take floating-point arguments may produce a different output[.](#strings-1.sentence-3) [*Example [1](#strings-example-1)*: auto s = std::to_string(1e-7); // "1e-07"// previously "0.000000" with '.' possibly// changed according to the global C locale — *end example*] ### [C.1.10](#io) [[input.output]](input.output "31 Input/output library"): input/output library [[diff.cpp23.io]](diff.cpp23.io) [1](#io-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L335) **Affected subclause:** [[istream.unformatted]](istream.unformatted) **Change:** Overloaded std​::​basic_istream​::​ignore[.](#io-1.sentence-1) **Rationale:** Allow char values to be used as delimiters[.](#io-1.sentence-2) **Effect on original feature:** Calls to istream​::​ignore with a second argument of char type can change behavior[.](#io-1.sentence-3) Calls to istream​::​ignore with a second argument that is neitherint nor char type can become ill-formed[.](#io-1.sentence-4) [*Example [1](#io-example-1)*: std::istringstream in("\xF0\x9F\xA4\xA1 Clown Face"); in.ignore(100, '\xA1'); // ignore up to '\xA1' delimiter,// previously might have ignored to EOF in.ignore(100, -1L); // ambiguous overload,// previously equivalent to (int)-1L — *end example*] ### [C.1.11](#depr) [[depr]](depr "Annex D (normative) Compatibility features"): compatibility features [[diff.cpp23.depr]](diff.cpp23.depr) [1](#depr-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L358) **Change:** Remove the type alias allocator​::​is_always_equal[.](#depr-1.sentence-1) **Rationale:** Non-empty allocator classes derived from allocator needed to explicitly define an is_always_equal member type so that allocator_traits would not use the one from the allocator base class[.](#depr-1.sentence-2) **Effect on original feature:** It is simpler to correctly define an allocator class with an allocator base class[.](#depr-1.sentence-3) [*Example [1](#depr-example-1)*: template struct MyAlloc : allocator {int tag;}; static_assert(!allocator_traits>::is_always_equal); // Error in C++ 2023,// OK in C++ 2026 — *end example*] [2](#depr-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L380) **Change:** Removal of atomic access API for shared_ptr objects[.](#depr-2.sentence-1) **Rationale:** The old behavior was brittle[.](#depr-2.sentence-2) shared_ptr objects using the old API were not protected by the type system, and certain interactions with code not using this API would, in some cases, silently produce undefined behavior[.](#depr-2.sentence-3) A complete type-safe replacement is provided in the form of atomic>[.](#depr-2.sentence-4) **Effect on original feature:** A valid C++ 2023 program that relies on the presence of the removed functions may fail to compile[.](#depr-2.sentence-5) [3](#depr-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L392) **Change:** Remove the basic_string​::​reserve() overload with no parameters[.](#depr-3.sentence-1) **Rationale:** The overload of reserve with no parameters is redundant[.](#depr-3.sentence-2) The shrink_to_fit member function can be used instead[.](#depr-3.sentence-3) **Effect on original feature:** A valid C++ 2023 program that calls reserve() on a basic_string object may fail to compile[.](#depr-3.sentence-4) The old functionality can be achieved by calling shrink_to_fit() instead, or the function call can be safely eliminated with no side effects[.](#depr-3.sentence-5) [4](#depr-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L404) **Change:** Remove header and all its contents[.](#depr-4.sentence-1) **Rationale:** The header has been deprecated for the previous three editions of this document and no longer implements the current Unicode standard, supporting only the obsolete UCS-2 encoding[.](#depr-4.sentence-2) Ongoing support is at implementer's discretion, exercising freedoms granted by [[zombie.names]](zombie.names "16.4.5.3.2 Zombie names")[.](#depr-4.sentence-3) **Effect on original feature:** A valid C++ 2023 program #include-ing the header or importing the header unit may fail to compile[.](#depr-4.sentence-4) Code that uses any of the following names by importing the standard library modules may fail to compile: - [(4.1)](#depr-4.1) codecvt_mode, - [(4.2)](#depr-4.2) codecvt_utf16, - [(4.3)](#depr-4.3) codecvt_utf8, - [(4.4)](#depr-4.4) codecvt_utf8_utf16, - [(4.5)](#depr-4.5) consume_header, - [(4.6)](#depr-4.6) generate_header, and - [(4.7)](#depr-4.7) little_endian[.](#depr-4.sentence-5) [5](#depr-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L427) **Change:** Remove header and all its contents[.](#depr-5.sentence-1) **Rationale:** The header has been deprecated since the original C++ standard; the[](span.streams.overview#header:%3cspanstream%3e "31.9.1 Overview [span.streams.overview]") header provides an updated, safer facility[.](#depr-5.sentence-2) Ongoing support is at implementer's discretion, exercising freedoms granted by [[zombie.names]](zombie.names "16.4.5.3.2 Zombie names")[.](#depr-5.sentence-3) **Effect on original feature:** A valid C++ 2023 program #include-ing the header or importing the header unit may become ill-formed[.](#depr-5.sentence-4) Code that uses any of the following classes by importing one of the standard library modules may become ill-formed: - [(5.1)](#depr-5.1) istrstream - [(5.2)](#depr-5.2) ostrstream - [(5.3)](#depr-5.3) strstream - [(5.4)](#depr-5.4) strstreambuf [6](#depr-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/compatibility.tex#L446) **Change:** Remove convenience interfaces wstring_convert andwbuffer_convert[.](#depr-6.sentence-1) **Rationale:** These features were underspecified with no clear error reporting mechanism and were deprecated for the last three editions of this document[.](#depr-6.sentence-2) Ongoing support is at implementer's discretion, exercising freedoms granted by [[zombie.names]](zombie.names "16.4.5.3.2 Zombie names")[.](#depr-6.sentence-3) **Effect on original feature:** A valid C++ 2023 program using these interfaces may become ill-formed[.](#depr-6.sentence-4)