Libc++ 20.0.0 (In-Progress) Release Notes

Written by the Libc++ Team

Warning

These are in-progress notes for the upcoming libc++ 20.0.0 release. Release notes for previous releases can be found on the Download Page.

Introduction

This document contains the release notes for the libc++ C++ Standard Library, part of the LLVM Compiler Infrastructure, release 20.0.0. Here we describe the status of libc++ in some detail, including major improvements from the previous release and new feature work. For the general LLVM release notes, see the LLVM documentation. All LLVM releases may be downloaded from the LLVM releases web site.

For more information about libc++, please see the Libc++ Web Site or the LLVM Web Site.

Note that if you are reading this file from a Git checkout or the main Libc++ web page, this document applies to the next release, not the current one. To see the release notes for a specific release, please see the releases page.

What’s New in Libc++ 20.0.0?

Implemented Papers

  • P0619R4: Reviewing Deprecated Facilities of C++17 for C++20 (Github)

  • P2747R2: constexpr placement new (Github)

  • P2609R3: Relaxing Ranges Just A Smidge (Github)

  • P2985R0: A type trait for detecting virtual base classes (Github)

  • std::jthread and <stop_token> are not guarded behind -fexperimental-library anymore

  • P2674R1: A trait for implicit lifetime types (Github)

  • P0429R9: A Standard flat_map is partially implemented and flat_map is provided (Github)

Improvements and New Features

  • The lexicographical_compare and ranges::lexicographical_compare algorithms have been optimized for trivially equality comparable types, resulting in a performance improvement of up to 40x.

  • The _LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER macro has been added to make std::get_temporary_buffer and std::return_temporary_buffer available.

  • The _LIBCPP_ENABLE_CXX20_REMOVED_UNCAUGHT_EXCEPTION macro has been added to make std::uncaught_exception available in C++20 and later modes.

  • The internal structure __compressed_pair has been replaced with [[no_unique_address]], resulting in reduced compile times and smaller debug information as well as better code generation if optimizations are disabled. The Chromium project measured a 5% reduction in object file and debug information size.

  • The _LIBCPP_ABI_BOUNDED_UNIQUE_PTR ABI configuration was added, which allows std::unique_ptr<T[]> to detect out-of-bounds accesses in certain circumstances. std::unique_ptr<T[]> can now also detect out-of-bounds accesses for a limited set of types (non-trivially destructible types) when the ABI configuration is disabled.

  • The _LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY ABI configuration was added, which allows storing valid bounds in std::array::iterator and detecting OOB accesses when the appropriate hardening mode is enabled.

Deprecations and Removals

  • The LIBCXX_ENABLE_ASSERTIONS CMake variable and the _LIBCPP_ENABLE_ASSERTIONS macro that were used to enable the safe mode have been removed in LLVM 20. Please use support for hardening instead.

  • Support for the C++20 synchronization library (<barrier>, <latch>, atomic::wait, etc.) has been removed in language modes prior to C++20. If you are using these features prior to C++20, you will need to update to -std=c++20.

  • TODO: The relational operators for std::chrono::weekday will be removed entirely, and the _LIBCPP_ENABLE_REMOVED_WEEKDAY_RELATIONAL_OPERATORS macro that was used to re-enable this extension will be ignored in LLVM 20.

  • The _LIBCPP_ENABLE_REMOVED_ALLOCATOR_CONST macro no longer has any effect. std::allocator<const T> is not supported as an extension anymore, please migrate any code that uses e.g. std::vector<const T> to be standards conforming.

  • Non-conforming member typedefs base, iterator and const_iterator of std::bitset, and member typedef base of std::forward_list and std::list are removed. Previously, they were private but could cause ambiguity in name lookup. Code that expects such ambiguity will possibly not compile in LLVM 20.

  • The function __libcpp_verbose_abort() is now noexcept, to match std::terminate(). (The combination of noexcept and [[noreturn]] has special significance for function effects analysis.) For backwards compatibility, the _LIBCPP_VERBOSE_ABORT_NOT_NOEXCEPT macro can be defined to make the function non-noexcept. That macro will be removed in LLVM 21.

  • <ccomplex>, <cstdalign> (previously missing), <cstdbool>, and <ctgmath> are deprecated since C++17 as specified by the standard. They, together with <ciso646>, are removed in C++20, but libc++ still provides these headers as an extension and only deprecates them. The _LIBCPP_DISABLE_DEPRECATION_WARNINGS macro can be defined to suppress deprecation for these headers.

Upcoming Deprecations and Removals

LLVM 21

  • The status of the C++03 implementation will be frozen after the LLVM 21 release. This means that starting in LLVM 22, non-critical bug fixes may not be back-ported to C++03, including LWG issues. C++03 is a legacy platform, where most projects are no longer actively maintained. To reduce the amount of fixes required to keep such legacy projects compiling with up-to-date toolchains, libc++ will aim to freeze the status of the headers in C++03 mode to avoid unintended breaking changes. See https://discourse.llvm.org/t/rfc-freezing-c-03-headers-in-libc for more details.

    If you are using C++03 in your project, you should consider moving to a newer version of the Standard to get the most out of libc++.

  • The _LIBCPP_VERBOSE_ABORT_NOT_NOEXCEPT macro will be removed in LLVM 21, making std::__libcpp_verbose_abort unconditionally noexcept.

ABI Affecting Changes

  • The ABI breaks for removing undefined behaviour in std::forward_list, std::list, std::map, std::set, std::multimap, std::multiset, std::unordered_map, std::unordered_set, std::unordered_multimap and std::unordered_multiset are now applied unconditionally. This only affects fancy pointers which have a different value representation when pointing at the base of an internal node type instead of the type itself. A size or alignment difference is diagnosed, but more subtle ABI breaks may result in unexpected behaviour.

  • The internal structure __compressed_pair has been replaced with [[no_unique_address]]. The ABI impact is:

    • When using the Itanium ABI (most non-MSVC platforms), empty types are now placed at the beginning of the enclosing object instead of where the beginning of the __compressed_pair subobject was. This is only observable by checking the address of the empty allocator, equality comparator or hasher.

    • Additionally, using an overaligned empty type as an allocator, comparator or hasher in the associative containers (and only those containers) may result in the container’s object object size and data layout changing beyond only the address of the empty member.

    • When using the MSVC ABI, this change results in some classes having a completely different memory layout, so this is a genuine ABI break. However, the library does not currently guarantee ABI stability on MSVC platforms.

Build System Changes

  • TODO