scripted-diff: Use inline const(expr) over static constexpr in headers #35852

pull maflcko wants to merge 9 commits into bitcoin:master from maflcko:2607-refactor-inline-constexpr changing 102 files +440 −440
  1. maflcko commented at 5:54 PM on July 30, 2026: member

    Both are fine and this refactor doesn't change any behavior.

    However, inline constexpr from C++17 will ensure each symbol has a single address across all TU, making the release binary minimally smaller. (For me it is smaller by about 1kB)

  2. DrahtBot renamed this:
    scripted-diff: Use inline constexpr over static constexpr in headers
    scripted-diff: Use inline constexpr over static constexpr in headers
    on Jul 30, 2026
  3. DrahtBot added the label Refactoring on Jul 30, 2026
  4. DrahtBot commented at 5:55 PM on July 30, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35852.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    ACK l0rinc, rustaceanrob, hebasto
    Stale ACK fanquake

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #35955 (wallet: remove orphaned GetAffectedKeys and LegacyScriptPubKeyMan declarations by laxmanacharya8)
    • #35948 (init: correct first-run disk space estimates by l0rinc)
    • #35888 (net: reject oversized outbound messages by l0rinc)
    • #35861 (Testnet 5 (BIP95) by fjahr)
    • #35820 (refactor: keep duration calculations typed by l0rinc)
    • #35793 (Implement BIP 54 (Consensus Cleanup) without mainnet activation by darosior)
    • #35752 (wallet: make encryption state updates atomic by l0rinc)
    • #35730 (http: limit connected HTTPRemoteClients by pinheadmz)
    • #35591 ([DO NOT MERGE] Erlay: bandwidth-efficient transaction relay protocol (Full implementation) by sr-gi)
    • #35569 (Encapsulation for CTransaction by purpleKarrot)
    • #35433 (wallet: deprecate replaceable argument from transaction (and psbt) creation (and modification) RPCs by rkrux)
    • #34565 (refactor: extract BlockDownloadManager from PeerManagerImpl by w0xlt)
    • #34400 (wallet: parallel fast rescan (approx 8x speed up with 8 threads) by Eunovo)
    • #34075 (fees: Introduce Mempool Based Fee Estimation to reduce overestimation by ismaelsadeeq)
    • #33112 (wallet: relax external_signer flag constraints, add musig2 test (partial) by Sjors)
    • #32857 (wallet: allow skipping script paths by Sjors)
    • #32729 (test,refactor: extract script template helpers and expand sigop coverage by l0rinc)
    • #32387 (ipc: add windows support by ryanofsky)
    • #30951 (net: option to disallow v1 connection on ipv4 and ipv6 peers by stratospher)
    • #29278 (Wallet: Add maxfeerate wallet startup option by ismaelsadeeq)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  5. fanquake commented at 8:24 PM on July 30, 2026: member

    Concept ACK - Could change static const here too? Not sure it's worth adding to the dev notes that inline constexpr is generally preferred (over static constexpr, static const etc)?

  6. in src/util/string.h:26 in fac31e6885 outdated
      22 | @@ -23,7 +23,7 @@
      23 |  namespace util {
      24 |  namespace detail {
      25 |  template <unsigned num_params>
      26 | -constexpr static void CheckNumFormatSpecifiers(const char* str)
    


    l0rinc commented at 8:27 PM on July 30, 2026:

    fac31e6 refactor: Manually use inline constexpr over constexpr static:

    This is already implicitly inline, if we're changing it in a separate commit, we might as well remove the modifier, preferably as a first commit, which would allow us to fix the other case here in the scripted diff.

    And maybe cover https://github.com/bitcoin/bitcoin/blob/fa5f29774872d18febc0df38831a6e45f3de69cc/src/net_permissions.h#L49 as well, similarly removing both qualifiers.


    maflcko commented at 8:26 AM on July 31, 2026:

    Sure, done both.

  7. in src/qt/guiconstants.h:20 in 6666d4c486
      17 |  /* A delay between shutdown pollings */
      18 | -static constexpr auto SHUTDOWN_POLLING_DELAY{200ms};
      19 | +inline constexpr auto SHUTDOWN_POLLING_DELAY{200ms};
      20 |  
      21 |  /* AskPassphraseDialog -- Maximum passphrase length */
      22 |  static const int MAX_PASSPHRASE_SIZE = 1024;
    


    l0rinc commented at 8:59 PM on July 30, 2026:

    fac31e6 refactor: Manually use inline constexpr over constexpr static:

    Maybe we could extend the PR to cover these as well (edit: #35852 (comment))


    maflcko commented at 8:26 AM on July 31, 2026:

    Sure, seems few enough to just include here as well.

  8. in src/key.h:28 in fac31e6885
      24 | @@ -25,7 +25,7 @@ typedef struct secp256k1_context_struct secp256k1_context;
      25 |  typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
      26 |  
      27 |  /** Size of ECDH shared secrets. */
      28 | -constexpr static size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
      29 | +inline constexpr size_t ECDH_SECRET_SIZE{CSHA256::OUTPUT_SIZE};
    


    l0rinc commented at 9:20 PM on July 30, 2026:

    fac31e6 refactor: Manually use inline constexpr over constexpr static:

    Could we rather extend the scripted diff to cover this?

    <details><summary>extended scripted diff</summary>

    sed -E -i 's/^(static constexpr|constexpr static)\>/inline constexpr/g' $( \
      git grep -El '^(static constexpr|constexpr static)' -- \
        '*.h' \
        ':(exclude)src/crc32c' \
        ':(exclude)src/ipc/libmultiprocess' \
        ':(exclude)src/minisketch' \
    )
    

    </details>


    maflcko commented at 8:26 AM on July 31, 2026:

    thx, done

  9. in src/common/bloom.h:1 in 6666d4c486 outdated


    l0rinc commented at 9:47 PM on July 30, 2026:

    6666d4c scripted-diff: Use inline constexpr over static constexpr:

    Verified that all 3 excludes are indeed needed 👍

  10. l0rinc approved
  11. maflcko force-pushed on Jul 31, 2026
  12. maflcko renamed this:
    scripted-diff: Use inline constexpr over static constexpr in headers
    scripted-diff: Use inline const(expr) over static constexpr in headers
    on Jul 31, 2026
  13. maflcko force-pushed on Jul 31, 2026
  14. DrahtBot added the label CI failed on Jul 31, 2026
  15. DrahtBot removed the label CI failed on Jul 31, 2026
  16. fanquake commented at 11:50 AM on July 31, 2026: member

    ACK fac8a3a4a68bc7edabaaab6bfb113199792babb4

  17. in src/chainparamsseeds.h:13 in fa41c7da8d outdated
       9 | @@ -10,7 +10,7 @@
      10 |   *
      11 |   * Each line contains a BIP155 serialized (networkID, addr, port) tuple.
      12 |   */
      13 | -static const uint8_t chainparams_seed_main[] = {
      14 | +inline constexpr uint8_t chainparams_seed_main[] = {
    


    l0rinc commented at 3:20 AM on August 3, 2026:

    fa41c7d scripted-diff: Use inline constexpr over static const:

    Regenerating the seeds would restore static const - could we update the generator as well?

    <details><summary>update the fixed-seed generator</summary>

    diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py
    --- a/contrib/seeds/generate-seeds.py
    +++ b/contrib/seeds/generate-seeds.py
    @@ -22,9 +22,9 @@ These files must consist of lines in the format
    
     The output will be several data structures with the peers in binary format:
    
    -   static const uint8_t chainparams_seed_{main,signet,test,testnet4}[]={
    +   inline constexpr uint8_t chainparams_seed_{main,signet,test,testnet4}[]={
        ...
        }
    
     These should be pasted into `src/chainparamsseeds.h`.
     '''
    @@ -137,7 +137,7 @@ def bip155_serialize(spec):
         return r
    
     def process_nodes(g, f, structname):
    -    g.write('static const uint8_t %s[] = {\n' % structname)
    +    g.write('inline constexpr uint8_t %s[] = {\n' % structname)
         for line in f:
             comment = line.find('#')
             if comment != -1:
    

    </details>


    maflcko commented at 9:39 AM on August 4, 2026:

    Ah, right. The header is included only once, so it shouldn't matter, but I've added a commit with you as co-author.


    l0rinc commented at 6:01 PM on August 4, 2026:

    Sorry about this, the generated files still differ, my mistake:

    diff -u src/chainparamsseeds.h <(python3 contrib/seeds/generate-seeds.py contrib/seeds) | egrep '[+-]' 
    --- src/chainparamsseeds.h      2026-08-04 10:43:25
    +++ /dev/fd/11  2026-08-04 10:58:07
    @@ -10,7 +10,7 @@
    -inline constexpr uint8_t chainparams_seed_main[] = {
    +inline constexpr uint8_t chainparams_seed_main[]{
    @@ -2072,7 +2072,7 @@
    -inline constexpr uint8_t chainparams_seed_signet[] = {
    +inline constexpr uint8_t chainparams_seed_signet[]{
    @@ -2245,7 +2245,7 @@
    -inline constexpr uint8_t chainparams_seed_test[] = {
    +inline constexpr uint8_t chainparams_seed_test[]{
    @@ -2429,7 +2429,7 @@
    -inline constexpr uint8_t chainparams_seed_testnet4[] = {
    +inline constexpr uint8_t chainparams_seed_testnet4[]{
    

    Though I'm find with leaving as is, the next generation will automatically fix these.

  18. in src/wallet/wallet.h:122 in fa41c7da8d
     122 |   * A value > 0 means to do partial spend avoidance if the fee difference against a regular coin selection instance is in the range [0..value].
     123 |   */
     124 | -static const CAmount DEFAULT_MAX_AVOIDPARTIALSPEND_FEE = 0;
     125 | +inline constexpr CAmount DEFAULT_MAX_AVOIDPARTIALSPEND_FEE = 0;
     126 |  //! discourage APS fee higher than this amount
     127 |  constexpr CAmount HIGH_APS_FEE{COIN / 10000};
    


    l0rinc commented at 8:29 PM on August 3, 2026:

    fa8f820 scripted-diff: Use inline constexpr over static constexpr:

    The current scripted diff only covers static constexpr values - could we cover non-static cases as well?

    sed -i -E 's/^constexpr .+ [A-Z0-9_]+(\[\])? ?[={]/inline &/' $( \
        git grep -l '^constexpr ' -- '*.h' ':(exclude)src/minisketch' \
    )
    

    maflcko commented at 9:39 AM on August 4, 2026:

    Hmm, this was already fixed in C++17, which adds the inline here. But I guess it can't hurt to be explicit here:

    • For consistency
    • To avoid devs accidentally adding static out of muscle memory (Hopefully static inline constexpr will look ugly enough for them to remove either inline or static.)
    • To explicitly say that this is inline (to avoid confusion with the older C++11/14 constexpr )

    Added a commit with your scripted-diff as co-author.

  19. in src/serialize.h:35 in fa8f820a20 outdated
      31 | @@ -32,7 +32,7 @@
      32 |   * The maximum size of a serialized object in bytes or number of elements
      33 |   * (for eg vectors) when the size is encoded as CompactSize.
      34 |   */
      35 | -static constexpr uint64_t MAX_SIZE = 0x02000000;
      36 | +inline constexpr uint64_t MAX_SIZE = 0x02000000;
    


    l0rinc commented at 8:33 PM on August 3, 2026:

    fa8f820 scripted-diff: Use inline constexpr over static constexpr:

    Could we cover SocketError and deserialize as well?

    diff --git a/src/ipc/util.h b/src/ipc/util.h
    index 6352f98174..03ce153417 100644
    --- a/src/ipc/util.h
    +++ b/src/ipc/util.h
    @@ -25,7 +25,7 @@ namespace mp {
     class EventLoop;
     using ProcessId = int;
     using SocketId = int;
    -constexpr SocketId SocketError{-1};
    +inline constexpr SocketId SocketError{-1};
    
     using Stream = SocketId;
     inline Stream MakeStream(EventLoop&, SocketId socket)
    diff --git a/src/serialize.h b/src/serialize.h
    index 4dbfe819b3..e6926b3579 100644
    --- a/src/serialize.h
    +++ b/src/serialize.h
    @@ -49,7 +49,7 @@ inline constexpr unsigned int MAX_VECTOR_ALLOCATE = 5000000;
      * is likely the only way to do so.
      */
     struct deserialize_type {};
    -constexpr deserialize_type deserialize {};
    +inline constexpr deserialize_type deserialize {};
    
     /*
      * Lowest-level serialization and conversion.
    

    maflcko commented at 9:39 AM on August 4, 2026:

    sure, done

  20. in src/psbt.h:93 in fa8f820a20
     137 | -static constexpr uint8_t PSBT_SEPARATOR = 0x00;
     138 | +inline constexpr uint8_t PSBT_SEPARATOR = 0x00;
     139 |  
     140 |  // BIP 174 does not specify a maximum file size, but we set a limit anyway
     141 |  // to prevent reading a stream indefinitely and running out of memory.
     142 |  const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MB
    


    l0rinc commented at 8:36 PM on August 3, 2026:

    fa41c7d scripted-diff: Use inline constexpr over static const:

    The scripted diff only covers static const values - could we cover non-static cases as well?

    type='auto|int|unsigned int|uint32_t|std::streamsize'
    sed -i -E "s/^const ($type) /inline constexpr \1 /" $( \
        git grep -lE "^const ($type) " -- '*.h' \
    )
    

    maflcko commented at 9:39 AM on August 4, 2026:

    sure, done

  21. in src/netbase.h:33 in fa41c7da8d
      30 |  //! -dns default
      31 | -static const int DEFAULT_NAME_LOOKUP = true;
      32 | +inline constexpr int DEFAULT_NAME_LOOKUP = true;
      33 |  
      34 |  /** Prefix for unix domain socket addresses (which are local filesystem paths) */
      35 |  const std::string ADDR_PREFIX_UNIX = "unix:";
    


    l0rinc commented at 8:38 PM on August 3, 2026:

    fa41c7d scripted-diff: Use inline constexpr over static const:

    The scripted diff still leaves non-static std::string and fs::path objects - could we cover those as well?

    sed -i -E 's/^const (fs::path|std::string) /inline &/' $( \
        git grep -lE '^const (fs::path|std::string) ' -- '*.h' \
    )
    

    maflcko commented at 9:39 AM on August 4, 2026:

    sure, done, but in a different commit and with a different script.

  22. in src/chain.h:29 in fa8f820a20 outdated
      25 | @@ -26,18 +26,18 @@
      26 |   * Maximum amount of time that a block timestamp is allowed to exceed the
      27 |   * current time before the block will be accepted.
      28 |   */
      29 | -static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60;
      30 | +inline constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60;
    


    l0rinc commented at 8:56 PM on August 3, 2026:

    fa8f820 scripted-diff: Use inline constexpr over static constexpr:

    These conflict directly with https://github.com/bitcoin/bitcoin/commit/861d3345fdbbf2ec8990a07e596312cc821ad3fd - after merge I'd appreciate a re-review.


    maflcko commented at 9:39 AM on August 4, 2026:

    What pull id is that? In any case, happy to let this one sit. A rebase should be trivial either way, as this pull is mostly scripted-diffs.


    l0rinc commented at 12:53 AM on August 18, 2026:

    I meant a re-review for #35820, but it's just a refactoring, it's also not urgent.

  23. in src/consensus/amount.h:15 in fa8f820a20
      11 | @@ -12,7 +12,7 @@
      12 |  typedef int64_t CAmount;
      13 |  
      14 |  /** The amount of satoshis in one BTC. */
      15 | -static constexpr CAmount COIN = 100000000;
      16 | +inline constexpr CAmount COIN = 100000000;
    


    l0rinc commented at 8:56 PM on August 3, 2026:

    fa8f820 scripted-diff: Use inline constexpr over static constexpr:

    nit: these are rarely written but often read, would be cool to sneak in some delimiters here:

    inline constexpr CAmount COIN = 100'000'000;
    

    maflcko commented at 9:39 AM on August 4, 2026:

    heh, I read those as 1'0000'0000

  24. in src/consensus/amount.h:26 in fa8f820a20
      22 | @@ -23,7 +23,7 @@ static constexpr CAmount COIN = 100000000;
      23 |   * critical; in unusual circumstances like a(nother) overflow bug that allowed
      24 |   * for the creation of coins out of thin air modification could lead to a fork.
      25 |   * */
      26 | -static constexpr CAmount MAX_MONEY = 21000000 * COIN;
      27 | +inline constexpr CAmount MAX_MONEY = 21000000 * COIN;
    


    l0rinc commented at 8:57 PM on August 3, 2026:

    fa8f820 scripted-diff: Use inline constexpr over static constexpr:

    same:

    inline constexpr CAmount MAX_MONEY = 21'000'000 * COIN;
    

    maflcko commented at 9:39 AM on August 4, 2026:

    Sure, done here and for a few others.


    l0rinc commented at 6:00 PM on August 4, 2026:

    Maybe my dream will come true https://github.com/bitcoin/bitcoin/pull/29444

  25. l0rinc approved
  26. l0rinc commented at 9:00 PM on August 3, 2026: contributor

    I left a few follow-ups for header values that retain internal linkage. Since generate-seeds.py still emits static const, the PR needs another push anyway, so perhaps the other cases could be folded into the existing scripted diffs or added as separate commits.

  27. maflcko force-pushed on Aug 4, 2026
  28. maflcko force-pushed on Aug 4, 2026
  29. DrahtBot added the label CI failed on Aug 4, 2026
  30. maflcko force-pushed on Aug 4, 2026
  31. DrahtBot removed the label CI failed on Aug 4, 2026
  32. l0rinc approved
  33. l0rinc commented at 6:15 PM on August 4, 2026: contributor

    tested ACK fa423e08734d25110b41287bcab398bb41f40b46

    Checked every line manually, rebased and tested locally.

  34. DrahtBot requested review from fanquake on Aug 4, 2026
  35. DrahtBot added the label Needs rebase on Aug 4, 2026
  36. refactor: Remove static from constexpr functions in headers
    Those functions have no need to be static in every TU. Also, static
    somewhat contradicts and overwrites the inline keyword.
    
    So remove the static, and just keep constexpr (which implies inline).
    fa6e1a1e85
  37. scripted-diff: Use inline constexpr over static constexpr
    Both are fine and this refactor shouldn't change any behavior.
    
    However, inline constexpr will ensure each symbol has a single address
    across all TU, making the release binary smaller.
    
    Review note: In theory the script may also cover functions, but they
    were handled in the prior commit, to remove the redundant inline for
    them.
    
    -BEGIN VERIFY SCRIPT-
     sed --regexp-extended -i 's/^(static constexpr|constexpr static)\>/inline constexpr/g' $( \
       git grep --extended-regexp -l '^(static constexpr|constexpr static)' -- \
         '*.h' \
         ':(exclude)src/crc32c' \
         ':(exclude)src/ipc/libmultiprocess' \
         ':(exclude)src/minisketch' \
     )
    -END VERIFY SCRIPT-
    5555d5dcb5
  38. refactor: Make CFeeRate(integral) ctor constexpr
    This is required for the next commit.
    
    Also, in a test, use `inline constexpr` for an `auto` type, which is
    also needed for the next commit, which hard-codes a list of types for
    conversion.
    faedb52583
  39. scripted-diff: Use inline constexpr over (static) const
    Both are fine and this refactor shouldn't change any behavior.
    
    However, inline constexpr will ensure each symbol has a single address
    across all TU, making the release binary smaller.
    
    Note, a follow-up commit will deal with string literals (const char*)
    and other static const, which can not be constexpr (e.g. std::vector).
    
    -BEGIN VERIFY SCRIPT-
     # Limit to types that can be constexpr
     type='bool|CAmount|size_t|((signed|unsigned) )?int|u?int[0-9]+_t|std::array|DatabaseFormat|CFeeRate|std::streamsize'
     sed -i --regexp-extended "s/^(static )?const (${type})\>/inline constexpr \2/" $( \
       git grep -l --extended-regexp "^(static )?const " -- \
         '*.h' \
         ':(exclude)src/leveldb' \
         ':(exclude)src/secp256k1' \
     )
    -END VERIFY SCRIPT-
    fad753611b
  40. contrib: Adjust generate-seeds.py to write inline constexpr
    Otherwise, the changes in the previous commit will be reverted when this
    script regenerates the header.
    
    Co-Authored-By: l0rinc <pap.lorinc@gmail.com>
    fa08bbed8d
  41. refactor: Use inline constexpr for string literals in headers
    This is needed for the next scripted-diff commit, which would otherwise
    turn the const from `static const char*` into `inline const char*`.
    fab1a62c87
  42. scripted-diff: Use inline const over (static) const
    Both are fine and this refactor shouldn't change any behavior.
    
    However, inline const will ensure each symbol has a single address
    across all TU, making the release binary smaller.
    
    -BEGIN VERIFY SCRIPT-
    
     # Replace `static const`
     sed -i "s/^static const /inline const /" $( \
       git grep -l "^static const " -- \
         '*.h' \
         ':(exclude)src/leveldb' \
         ':(exclude)src/secp256k1' \
     )
    
     # Replace plain `const`
     sed -i --regexp-extended 's/^const (\S+ \w+(\[\])? ?[={])/inline &/' $( \
       git grep -l '^const ' -- \
         '*.h' \
         ':(exclude)src/leveldb' \
         ':(exclude)src/secp256k1' \
       )
    
    -END VERIFY SCRIPT-
    fa74f58a26
  43. scripted-diff: Use inline constexpr over plain constexpr
    Both are identical since C++17 and this refactor shouldn't change any
    behavior. The benefits are consistency and to be explicit, to avoid
    confusion with the C++11/14 constexpr.
    
    Co-Authored-By: l0rinc <pap.lorinc@gmail.com>
    
    -BEGIN VERIFY SCRIPT-
     sed -i --regexp-extended 's/^constexpr \S+ \w+(\[\])? ?[={]/inline &/' $( \
         git grep -l '^constexpr ' -- \
           '*.h' \
           ':(exclude)src/minisketch' \
     )
    -END VERIFY SCRIPT-
    fae759be79
  44. refactor: Use C++14 digit separator for large int literals
    Suggested by l0rinc.
    
    Co-Authored-By: l0rinc <pap.lorinc@gmail.com>
    fab74a0e92
  45. maflcko force-pushed on Aug 5, 2026
  46. l0rinc commented at 7:08 AM on August 5, 2026: contributor

    reACK fab74a0e922c6eb6501c3852ae08a24aade3850d

  47. DrahtBot removed the label Needs rebase on Aug 5, 2026
  48. rustaceanrob commented at 6:46 PM on August 13, 2026: member

    ACK fab74a0e922c6eb6501c3852ae08a24aade3850d

  49. hebasto approved
  50. hebasto commented at 8:51 AM on August 14, 2026: member

    ACK fab74a0e922c6eb6501c3852ae08a24aade3850d, I have reviewed the code and it looks OK.

  51. fanquake merged this on Aug 14, 2026
  52. fanquake closed this on Aug 14, 2026

  53. maflcko deleted the branch on Aug 17, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-08-21 19:50 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me