#36033 [wip,nomerge,rfc] build: Require C++23 compiler

ReviewabilityReviewsAgreementSize
#36033 maflcko [wip,nomerge,rfc] build: Require C++23 compilerNeeds rebase0Positive67 + 34 tests
  • Eliminate accumulating in-tree polyfills and workarounds by raising compiler requirements to C++23
  • Unblock downstream dependencies and future C++23 language features across the project
  • CI is failing, check whether the failure is from this PR before deep review
  • Concept approval without stated reasons (l0rinc)
  • Informational observation on include heuristics with no objections raised (hebasto)
  • 67 lines added or modified outside tests
  • 34 lines added or modified in tests
  • 409 lines removed in total
  • 56 files, 9 commits
Build and CI#14 of 56
P2 · unblocks #34979
  • P2 because it unblocks features tracked in #34979 and dependent projects like libmultiprocess
  • Removes accumulating toolchain workarounds across build environments
  • Ranking pass: Placed below its two prerequisite bumps (#36042, #36036) since progress depends on them landing first
Utilities (logging, arguments, libraries)#45 of 59
P3 · cleanup
  • P3 because it cleans up in-tree utility polyfills in favor of standard library implementations
  • Affects internal utility primitives without user-visible impact
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

This pull request raises the minimum C++ standard from C++20 to C++23 across CMake, depends, and CI, bumping minimum compiler requirements to GCC 13 and Clang 19. It replaces in-tree polyfills with standard library equivalents like std::expected and std::byteswap, removes obsolete workarounds like ALWAYS_FALSE, and adopts C++23 features such as std::string::contains and std::views::zip.

Problem: Maintaining C++20 compatibility forces developers to write and maintain polyfills and workarounds in-tree, while dependent projects such as libmultiprocess have already begun using C++23 features.

Evidence of importance:

  • PR description: 'the workarounds to avoid C++23 keep accumulating and some parts of the code already use C++23 features, such as lambda attributes' (linking to libmultiprocess commit bdd0cd6)
  • PR description: notes that requiring C++23 unlocks future features tracked in issue #34979 while bumping compiler requirements to GCC 13 and Clang 19

Scope: Draft RFC with wide mechanical churn: replaces string find idioms with std::string::contains across dozens of test and source files.

Risk of a mistake: medium (build). Bumping compiler version requirements to GCC 13 and Clang 19 can break builds on older developer systems and distros.

Changed since the previous assessment: Added include-what-you-use adjustments and direct inclusions of <expected> in multiple source files to satisfy include linters.

Reviewability

Ready · Needs rebase

Conflicts with master; review the logic now, the rebase is mechanical.

Waiting on (from the thread read):

  • decision: consensus on bumping minimum compiler requirements to C++23

Agreement

Positive

support without stated reasons, no open objection (l0rinc)

Thread notes: Re-read confirmed no objections or suggestions raised. hebasto's comment was an informational observation about IWYU heuristics. / Re-read statements under the updated schema. No claims were raised; hebasto's comment was an informational observation regarding IWYU heuristics.

Objections, suggestions, and questions: none recorded.

Support:

  • l0rinc (member) (Concept ACK, 2026-08-21): Concept ACK [not substantive]

Participants:

  • l0rinc (member, support, 1 statements 2026-08-21 to 2026-08-21): Concept ACK
  • hebasto (member, neutral, 1 statements 2026-08-23 to 2026-08-23): noted an include change was due to IWYU heuristics

Dependencies

Enables:

Files

203 lines under test/bench/ci.

  • src/test/util_expected_tests.cpp +0/-134
  • src/util/expected.h +5/-117
  • src/compat/byteswap.h +7/-60
  • src/compat/endian.h +12/-12
  • src/bitcoin-tx.cpp +6/-6
  • src/util/types.h +0/-12
  • src/kernel/bitcoinkernel.cpp +6/-4
  • src/test/getarg_tests.cpp +5/-5
  • src/test/netbase_tests.cpp +5/-5
  • src/test/fuzz/strprintf.cpp +4/-4
  • src/test/httpserver_tests.cpp +3/-3
  • src/test/system_tests.cpp +3/-3
  • src/rpc/util.cpp +2/-3
  • doc/release-notes-36033.md +4/-0
  • src/qt/guiutil.cpp +2/-2
  • src/wallet/test/coinselection_tests.cpp +2/-2
  • src/wallet/test/coinselector_tests.cpp +2/-2
  • src/logging/timer.h +1/-2
  • CMakeLists.txt +1/-1
  • ci/test/00_setup_env_native_asan.sh +1/-1
  • contrib/devtools/bitcoin-tidy/CMakeLists.txt +1/-1
  • depends/Makefile +1/-1
  • depends/README.md +1/-1
  • src/.clang-format +1/-1
  • src/bitcoin-cli.cpp +1/-1
  • src/common/args.cpp +1/-1
  • src/common/config.cpp +1/-1
  • src/common/license_info.cpp +1/-1
  • src/httpserver.cpp +1/-1
  • src/i2p.cpp +1/-1
  • src/qt/optionsmodel.cpp +1/-1
  • src/qt/transactiondesc.cpp +1/-1
  • src/rpc/net.cpp +1/-1
  • src/rpc/server.cpp +1/-1
  • src/test/argsman_tests.cpp +1/-1
  • src/test/dbwrapper_tests.cpp +1/-1
  • src/test/descriptor_tests.cpp +1/-1
  • src/test/fuzz/rpc.cpp +1/-1
  • src/test/fuzz/system.cpp +1/-1
  • src/test/util/common.h +1/-1
  • src/test/util/logging.cpp +1/-1
  • src/util/strencodings.cpp +1/-1
  • src/util/string.h +1/-1
  • src/wallet/test/wallet_tests.cpp +1/-1
  • src/wallet/wallet.cpp +1/-1
  • src/common/bip352.cpp +1/-0
  • src/index/txospenderindex.cpp +1/-0
  • src/node/blockstorage.cpp +1/-0
  • src/rpc/blockchain.cpp +0/-1
  • src/rpc/fees.cpp +0/-1
  • src/rpc/mempool.cpp +0/-1
  • src/rpc/rawtransaction.cpp +0/-1
  • src/script/descriptor.cpp +0/-1
  • src/test/CMakeLists.txt +0/-1
  • src/util/bip32.cpp +1/-0
  • src/util/fees.h +1/-0

Card

The short text the ranking pass compares across PRs.

This pull request raises the minimum C++ standard from C++20 to C++23, bumping minimum compiler requirements to GCC 13 and Clang 19. It replaces custom polyfills such as util::Expected and byteswap implementations with standard library equivalents like std::expected and std::byteswap, while adopting modern idioms like std::string::contains and std::views::zip across the codebase. The author notes that workarounds to avoid C++23 keep accumulating while external dependencies like libmultiprocess already use C++23 features. This draft RFC is intended to unblock work tracked in #34979.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-23T01:15, confidence high, input hash 784d6eb314c6c861
thread read through 2026-08-23 (2 statements), head 0af81cd6f9
labels: Needs rebase, CI failed · draft

Categories

Build and CI

P2 · unblocks #34979 (ranking pass: Placed below its two prerequisite bumps (#36042, #36036) since progress depends on them landing first)

Raises baseline toolchain requirements to C++23 across all build environments, removing accumulating build workarounds and unblocking features tracked in #34979 as well as dependent projects like libmultiprocess.

Membership: Changes minimum C++ standard in CMakeLists.txt, depends/Makefile, and CI configurations, raising compiler minimums to GCC 13 and Clang 19.

Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 2

Utilities (logging, arguments, libraries)

P3 · cleanup

Removes custom polyfill headers and workarounds across common utility primitives by delegating them to standard C++23 library implementations.

Membership: Retires in-tree polyfills in src/util/expected.h, src/compat/byteswap.h, and src/util/types.h in favor of std::expected and std::byteswap.

Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 2