Annex C (informative) Compatibility [diff]

C.1 C++ and ISO C++ 2023 [diff.cpp23]

C.1.1 General [diff.cpp23.general]

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

C.1.2 [expr]: expressions [diff.cpp23.expr]

Affected subclause: [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.

Rationale: Reinforcing type safety.

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.
For example: enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // ill-formed; previously well-formed int k = f - e; // ill-formed; previously well-formed auto x = true ? e : f; // ill-formed; previously well-formed

C.1.3 [dcl.dcl]: Declarations [diff.cpp23.dcl.dcl]

Affected subclause: [dcl.init.list]
Change: Pointer comparisons between initializer_list objects' backing arrays are unspecified.

Rationale: Permit the implementation to store backing arrays in static read-only memory.

Effect on original feature: Valid C++ 2023 code that relies on the result of pointer comparison between backing arrays may change behavior.
For example: bool ne(std::initializer_list<int> a, std::initializer_list<int> b) { return a.begin() != b.begin() + 1; } bool b = ne({2,3}, {1,2,3}); // unspecified result; previously false
Affected subclause: [dcl.array]
Change: Previously, T...[n] would declare a pack of function parameters.
T...[n] is now a pack-index-specifier.

Rationale: Improve the handling of packs.

Effect on original feature: Valid C++ 2023 code that declares a pack of parameters without specifying a declarator-id becomes ill-formed.
For example: template <typename... T> void f(T... [1]); template <typename... T> void g(T... ptr[1]); int main() { f<int, double>(nullptr, nullptr); // ill-formed, previously void f<int, double>(int [1], double [1]) g<int, double>(nullptr, nullptr); // ok }

C.1.4 [library]: library introduction [diff.cpp23.library]

Affected subclause: [headers]
Change: New headers.

Rationale: New functionality.

Effect on original feature: The following C++ headers are new: <debugging>, <hazard_pointer>, <linalg>, <rcu>, and <text_encoding>.
Valid C++ 2023 code that #includes headers with these names may be invalid in this revision of C++.

C.1.5 [strings]: strings library [diff.cpp23.strings]

Affected subclause: [string.conversions]
Change: Output of floating-point overloads of to_string and to_wstring.

Rationale: Prevent loss of information and improve consistency with other formatting facilities.

Effect on original feature: to_string and to_wstring function calls that take floating-point arguments may produce a different output.
For example: auto s = std::to_string(1e-7); // "1e-07" // previously "0.000000" with '.' possibly // changed according to the global C locale

C.1.6 [containers]: containers library [diff.cpp23.containers]

Affected subclause: [span.overview]
Change: span<const T> is constructible from initializer_list<T>.

Rationale: Permit passing a braced initializer list to a function taking span.

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++.
For example: void one(pair<int, int>); // #1 void one(span<const int>); // #2 void t1() { one({1, 2}); } // ambiguous between #1 and #2; previously called #1 void two(span<const int, 2>); void t2() { two({{1, 2}}); } // ill-formed; previously well-formed void *a[10]; int x = span<void* const>{a, 0}.size(); // x is 2; previously 0 any b[10]; int y = span<const any>{b, b + 10}.size(); // y is 2; previously 10

C.1.7 [depr]: compatibility features [diff.cpp23.depr]

Change: Remove the type alias allocator<T>​::​is_always_equal.

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.

Effect on original feature: It is simpler to correctly define an allocator class with an allocator base class.
For example: template <class T> struct MyAlloc : allocator<T> { int tag; }; static_assert(!allocator_traits<MyAlloc<int>>::is_always_equal); // Error in C++ 2023, // OK in C++ 2026
Change: Remove the basic_string​::​reserve() overload with no parameters.

Rationale: The overload of reserve with no parameters is redundant.
The shrink_to_fit member function can be used instead.

Effect on original feature: A valid C++ 2023 program that calls reserve() on a basic_string object may fail to compile.
The old functionality can be achieved by calling shrink_to_fit() instead, or the function call can be safely eliminated with no side effects.
Change: Remove header <codecvt> and all its contents.

Rationale: The header has been deprecated for the previous three editions of this standard and no longer implements the current Unicode standard, supporting only the obsolete UCS-2 encoding.
Ongoing support is at implementer's discretion, exercising freedoms granted by [zombie.names].

Effect on original feature: A valid C++ 2023 program #include-ing the header or importing the header unit may fail to compile.
Code that uses any of the following names by importing the standard library modules may fail to compile: