Don't assert(foo()) where foo() has side effects #13534

pull practicalswift wants to merge 1 commits into bitcoin:master from practicalswift:assert-with-a-side-effect changing 5 files +14 −8
  1. practicalswift commented at 12:13 PM on June 25, 2018: contributor

    Don't assert(foo()) where foo has side effects.

    From assert(3):

    If the macro NDEBUG is defined at the moment <assert.h> was last included, the macro assert() generates no code, and hence does nothing at all.

    Bitcoin currently cannot be compiled without assertions, but we shouldn't rely on that.

  2. practicalswift renamed this:
    Don't assert(foo()) where foo has side effects
    Don't assert(foo()) where foo() has side effects
    on Jun 25, 2018
  3. fanquake added the label Refactoring on Jun 25, 2018
  4. MarcoFalke commented at 12:20 PM on June 25, 2018: member

    Is this the only place in the code where this needs fixing?

  5. in src/bench/block_assemble.cpp:45 in 5df902d992 outdated
      40 | @@ -41,7 +41,8 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
      41 |      auto block = PrepareBlock(coinbase_scriptPubKey);
      42 |  
      43 |      while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
      44 | -        assert(++block->nNonce);
      45 | +        auto nNonce = ++block->nNonce;
      46 | +        assert(nNonce);
    


    MarcoFalke commented at 12:22 PM on June 25, 2018:

    You can just remove the assert. This is regtest, so a wrap is "impossible" anyway.


    practicalswift commented at 12:33 PM on June 25, 2018:

    Like this?

         while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
             ++block->nNonce;
         }
    

    MarcoFalke commented at 12:40 PM on June 25, 2018:

    sure

  6. practicalswift force-pushed on Jun 25, 2018
  7. MarcoFalke commented at 9:56 PM on June 25, 2018: member

    Again, I believe we use this excessively in other parts of the code. What makes you fix this specific instance?

  8. practicalswift commented at 12:53 PM on June 26, 2018: contributor

    @MarcoFalke This is the only instance I know of where the assert(…) includes a function or expression that has a side effect (or more specifically where the execution would differ between defined(NDEBUG) vs. !defined(NDEBUG) beyond assert(...) obviously being expanded to a noop in the former case). Can you find another example? :-)

    Candidates:

    git grep '[^_]assert(.*);' | \
        grep -vE '^(build-aux/|src/(crypto/ctaes/|leveldb/|univalue/))'
    
  9. MarcoFalke commented at 1:55 PM on June 26, 2018: member

    They sound a bit like side-effects, haven't checked:

    $ git grep 'assert(' src/bench/checkblock.cpp src/httprpc.cpp
    src/bench/checkblock.cpp:        assert(stream.Rewind(sizeof(block_bench::block413567)));
    src/bench/checkblock.cpp:        assert(stream.Rewind(sizeof(block_bench::block413567)));
    src/bench/checkblock.cpp:        assert(CheckBlock(block, validationState, chainParams->GetConsensus()));
    src/httprpc.cpp:    assert(EventBase());
    
  10. practicalswift force-pushed on Jun 26, 2018
  11. practicalswift commented at 3:21 PM on June 26, 2018: contributor

    @MarcoFalke ++block->nNonce case is special in that block is used after the assert(…) takes place. I've now included the cases you mentioned and two others. Please re-review :-)

  12. practicalswift force-pushed on Jun 26, 2018
  13. promag commented at 7:06 AM on June 29, 2018: member

    Concept ACK.

  14. in src/httprpc.cpp:245 in 9047ddbf31 outdated
     239 | @@ -240,7 +240,8 @@ bool StartHTTPRPC()
     240 |      // ifdef can be removed once we switch to better endpoint support and API versioning
     241 |      RegisterHTTPHandler("/wallet/", false, HTTPReq_JSONRPC);
     242 |  #endif
     243 | -    assert(EventBase());
     244 | +    auto eventBase = EventBase();
     245 | +    assert(eventBase);
     246 |      httpRPCTimerInterface = MakeUnique<HTTPRPCTimerInterface>(EventBase());
    


    Empact commented at 8:37 PM on July 2, 2018:

    nit: Could reuse eventBase on this line. The type struct event_base* could be informative, given it makes the assert's meaning clear.


    laanwj commented at 1:49 PM on July 4, 2018:

    I agree. If we assign this to a variable anyway, we should use that. Note, though, that EventBase() has no side effects, it is fully a getter function.

  15. in src/bench/block_assemble.cpp:44 in 9047ddbf31 outdated
      40 | @@ -41,7 +41,7 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
      41 |      auto block = PrepareBlock(coinbase_scriptPubKey);
      42 |  
      43 |      while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
      44 | -        assert(++block->nNonce);
      45 | +        ++block->nNonce;
    


    Empact commented at 8:39 PM on July 2, 2018:

    The ->nNonce access has no effect without the assert. I would be in favor of keeping the assert on the following line. Or something like:

    while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus()) && ++block) {
        assert(block->nNonce);
    }
    

    promag commented at 9:07 PM on July 8, 2018:

    ++block?

    Note that this is as: assert(++(block->nNonce));


    Empact commented at 3:11 AM on July 9, 2018:

    Thanks, yeah figured that out here: #13534 (review) :P

  16. Empact commented at 8:39 PM on July 2, 2018: member

    Concept ACK

  17. practicalswift force-pushed on Jul 6, 2018
  18. practicalswift force-pushed on Jul 6, 2018
  19. practicalswift commented at 8:33 AM on July 6, 2018: contributor

    @Empact @laanwj @promag Thanks for reviewing. Updated. Please re-review :-)

  20. in src/bench/block_assemble.cpp:45 in 9025145dc6 outdated
      39 | @@ -40,8 +40,8 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
      40 |  {
      41 |      auto block = PrepareBlock(coinbase_scriptPubKey);
      42 |  
      43 | -    while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
      44 | -        assert(++block->nNonce);
      45 | +    while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus()) && ++block->nNonce) {
      46 | +        assert(block->nNonce);
    


    Empact commented at 10:47 AM on July 6, 2018:

    This will never fail on account of ->nNonce being in the while condition.

  21. practicalswift force-pushed on Jul 6, 2018
  22. practicalswift commented at 4:41 PM on July 6, 2018: contributor

    @Empact Good point. Feedback addressed. Please re-review :-)

  23. in src/bench/block_assemble.cpp:45 in acd9c045a0 outdated
      39 | @@ -40,8 +40,8 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
      40 |  {
      41 |      auto block = PrepareBlock(coinbase_scriptPubKey);
      42 |  
      43 | -    while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
      44 | -        assert(++block->nNonce);
      45 | +    while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus()) && block->nNonce++) {
      46 | +        assert(block->nNonce);
    


    Empact commented at 9:20 PM on July 6, 2018:

    Ok I realize I misread the precedence when I originally suggested to put it in the while condition. Sorry about that. Now I think it'd be better to put it in the block and let the assert do its thing. :P

  24. practicalswift force-pushed on Jul 6, 2018
  25. practicalswift force-pushed on Jul 6, 2018
  26. practicalswift commented at 10:08 PM on July 6, 2018: contributor

    @Empact Please re-review :-)

  27. in src/bench/block_assemble.cpp:44 in b0040a91f0 outdated
      40 | @@ -41,7 +41,8 @@ static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
      41 |      auto block = PrepareBlock(coinbase_scriptPubKey);
      42 |  
      43 |      while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
      44 | -        assert(++block->nNonce);
      45 | +        block->nNonce++;
    


    Empact commented at 1:11 AM on July 7, 2018:

    nit: could be ++block->nNonce as before


    practicalswift commented at 8:10 AM on July 7, 2018:

    @Empact Updated. Please re-review :-)

  28. Empact commented at 1:12 AM on July 7, 2018: member

    utACK b0040a9

  29. Don't assert(foo()) where foo has side effects 6ad0328f1c
  30. practicalswift force-pushed on Jul 7, 2018
  31. Empact commented at 2:20 PM on July 7, 2018: member

    re-utACK 6ad0328

  32. promag commented at 9:12 PM on July 8, 2018: member

    utACK 6ad0328.

  33. gmaxwell commented at 8:30 AM on July 10, 2018: contributor

    per our own style guide:

    • Assertions should not have side-effects

      • Rationale: Even though the source code is set to refuse to compile with assertions disabled, having side-effects in assertions is unexpected and makes the code harder to understand

    Several people have in the past swept through the code and fixed these things, and they should keep getting fixed, so CONCEPT ACK. Unfortunately, history has shown they keep creeping back in, thus the refusal to build without asserts. :)

  34. MarcoFalke commented at 4:29 PM on July 10, 2018: member

    utACK 6ad0328

  35. ken2812221 commented at 5:01 AM on August 10, 2018: contributor

    utACK 6ad0328

  36. MarcoFalke merged this on Aug 13, 2018
  37. MarcoFalke closed this on Aug 13, 2018

  38. ken2812221 referenced this in commit f87d0a9d75 on Aug 13, 2018
  39. laanwj referenced this in commit 709a15b0a6 on Aug 31, 2018
  40. jasonbcox referenced this in commit 46cdf26c9f on Dec 20, 2019
  41. jonspock referenced this in commit cb9855719d on Dec 29, 2019
  42. jonspock referenced this in commit bdbedca386 on Dec 30, 2019
  43. practicalswift deleted the branch on Apr 10, 2021
  44. PastaPastaPasta referenced this in commit 969de22347 on Jun 27, 2021
  45. PastaPastaPasta referenced this in commit b5a3283124 on Jun 28, 2021
  46. Munkybooty referenced this in commit e4b6a785ee on Jun 28, 2021
  47. Munkybooty referenced this in commit e1e343e694 on Jun 28, 2021
  48. Munkybooty referenced this in commit f142cf7fd9 on Jun 28, 2021
  49. PastaPastaPasta referenced this in commit 5303574f90 on Jun 29, 2021
  50. Munkybooty referenced this in commit e9512b8dae on Jun 29, 2021
  51. Munkybooty referenced this in commit aa7f7abd44 on Jun 29, 2021
  52. Munkybooty referenced this in commit 92a4fb7cf9 on Jun 29, 2021
  53. PastaPastaPasta referenced this in commit 60c722151f on Jun 29, 2021
  54. PastaPastaPasta referenced this in commit 689230b978 on Jun 29, 2021
  55. PastaPastaPasta referenced this in commit 658d86e0d4 on Jun 29, 2021
  56. PastaPastaPasta referenced this in commit 989e01887d on Jun 29, 2021
  57. Munkybooty referenced this in commit ccd75fbeda on Jun 29, 2021
  58. Munkybooty referenced this in commit edf52ad5c4 on Jun 29, 2021
  59. PastaPastaPasta referenced this in commit cd5a39c8af on Jul 1, 2021
  60. kittywhiskers referenced this in commit 7517e36a8b on Oct 12, 2021
  61. kittywhiskers referenced this in commit 154f4ce182 on Oct 12, 2021
  62. kittywhiskers referenced this in commit ef7aa29cc3 on Oct 12, 2021
  63. kittywhiskers referenced this in commit a86b67d040 on Oct 25, 2021
  64. pravblockc referenced this in commit cc96d5b924 on Nov 18, 2021
  65. gades referenced this in commit 31da93166f on Apr 29, 2022
  66. DrahtBot locked this on Aug 16, 2022

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-04-16 15:15 UTC

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