Skip to content

Conversation

@practicalswift
Copy link
Contributor

@practicalswift practicalswift commented Jun 25, 2018

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.

@practicalswift practicalswift changed the title Don't assert(foo()) where foo has side effects Don't assert(foo()) where foo() has side effects Jun 25, 2018
@maflcko
Copy link
Member

maflcko commented Jun 25, 2018

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this?

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch from 5df902d to 6421b84 Compare June 25, 2018 14:47
@maflcko
Copy link
Member

maflcko commented Jun 25, 2018

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

@practicalswift
Copy link
Contributor Author

practicalswift commented Jun 26, 2018

@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/))'

@maflcko
Copy link
Member

maflcko commented Jun 26, 2018

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());

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch from 6421b84 to 4728a85 Compare June 26, 2018 15:17
@practicalswift
Copy link
Contributor Author

@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 :-)

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch from 4728a85 to 9047ddb Compare June 26, 2018 15:23
@promag
Copy link
Contributor

promag commented Jun 29, 2018

Concept ACK.

src/httprpc.cpp Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

@laanwj laanwj Jul 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

@Empact Empact Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++block?

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@Empact
Copy link
Contributor

Empact commented Jul 2, 2018

Concept ACK

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch 2 times, most recently from 874dc9e to 9025145 Compare July 6, 2018 08:32
@practicalswift
Copy link
Contributor Author

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch from 9025145 to acd9c04 Compare July 6, 2018 16:34
@practicalswift
Copy link
Contributor Author

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch 2 times, most recently from 2ec358e to b0040a9 Compare July 6, 2018 22:07
@practicalswift
Copy link
Contributor Author

@Empact Please re-review :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Empact Updated. Please re-review :-)

@Empact
Copy link
Contributor

Empact commented Jul 7, 2018

utACK b0040a9

@practicalswift practicalswift force-pushed the assert-with-a-side-effect branch from b0040a9 to 6ad0328 Compare July 7, 2018 08:09
@Empact
Copy link
Contributor

Empact commented Jul 7, 2018

re-utACK 6ad0328

laanwj added a commit that referenced this pull request Aug 31, 2018
ca1a093 Add regression test: Don't assert(...) with side effects (practicalswift)
4c3c9c3 Don't assert(...) with side effects (practicalswift)

Pull request description:

  Don't `assert(...)` with side effects.

  From the developer notes:

  > **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

  These assertions were introduced quite recently (in #14069 which was merged two days ago) and since this is a recurring thing (see #13534 – "Don't assert(foo()) where foo() has side effects" from May) I added a simple regression test for the most obvious common side effect.

Tree-SHA512: be65db9d8d5d0f5752152ba73fe3fbb0531880f156d3cd7dfdf1752709979b63214e46ae64b1adbe1e09fa121278f4087f4ae49bff16cf8f5aec16ea6bde3650
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Dec 20, 2019
Summary:
6ad0328f1c Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

Partial backport of Core PR13534
bitcoin/bitcoin#13534

Test Plan:
  make check

Reviewers: deadalnix, Fabien, jasonbcox, O1 Bitcoin ABC, #bitcoin_abc

Reviewed By: Fabien, O1 Bitcoin ABC, #bitcoin_abc

Differential Revision: https://reviews.bitcoinabc.org/D4736
jonspock pushed a commit to jonspock/devault that referenced this pull request Dec 29, 2019
Summary:
6ad0328f1c Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

Partial backport of Core PR13534
bitcoin/bitcoin#13534

Test Plan:
  make check

Reviewers: deadalnix, Fabien, jasonbcox, O1 Bitcoin ABC, #bitcoin_abc

Reviewed By: Fabien, O1 Bitcoin ABC, #bitcoin_abc

Differential Revision: https://reviews.bitcoinabc.org/D4736
jonspock pushed a commit to devaultcrypto/devault that referenced this pull request Dec 30, 2019
Summary:
6ad0328f1c Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

Partial backport of Core PR13534
bitcoin/bitcoin#13534

Test Plan:
  make check

Reviewers: deadalnix, Fabien, jasonbcox, O1 Bitcoin ABC, #bitcoin_abc

Reviewed By: Fabien, O1 Bitcoin ABC, #bitcoin_abc

Differential Revision: https://reviews.bitcoinabc.org/D4736
@practicalswift practicalswift deleted the assert-with-a-side-effect branch April 10, 2021 19:35
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 28, 2021
6ad0328 Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

# Conflicts:
#	src/bench/block_assemble.cpp
#	src/bench/checkblock.cpp
#	src/script/sign.cpp
Munkybooty pushed a commit to Munkybooty/dash that referenced this pull request Jun 29, 2021
6ad0328 Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

# Conflicts:
#	src/bench/block_assemble.cpp
#	src/bench/checkblock.cpp
#	src/script/sign.cpp
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jul 1, 2021
ca1a093 Add regression test: Don't assert(...) with side effects (practicalswift)
4c3c9c3 Don't assert(...) with side effects (practicalswift)

Pull request description:

  Don't `assert(...)` with side effects.

  From the developer notes:

  > **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

  These assertions were introduced quite recently (in bitcoin#14069 which was merged two days ago) and since this is a recurring thing (see bitcoin#13534 – "Don't assert(foo()) where foo() has side effects" from May) I added a simple regression test for the most obvious common side effect.

Tree-SHA512: be65db9d8d5d0f5752152ba73fe3fbb0531880f156d3cd7dfdf1752709979b63214e46ae64b1adbe1e09fa121278f4087f4ae49bff16cf8f5aec16ea6bde3650
kwvg added a commit to kwvg/dash that referenced this pull request Oct 25, 2021
pravblockc pushed a commit to pravblockc/dash that referenced this pull request Nov 18, 2021
gades pushed a commit to cosanta/cosanta-core that referenced this pull request Apr 29, 2022
6ad0328 Don't assert(foo()) where foo has side effects (practicalswift)

Pull request description:

  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.

Tree-SHA512: 28cff0c6d1c2fb612ca58c9c94142ed01c5cfd0a2fecb8e59cdb6c270374b215d952ed3491d921d84dc1b439fa49da4f0e75e080f6adcbc6b0e08be14e54c170

# Conflicts:
#	src/bench/block_assemble.cpp
#	src/bench/checkblock.cpp
#	src/script/sign.cpp
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants