logoalt Hacker News

MontagFTBtoday at 4:23 PM6 repliesview on HN

Putting code with side effects into an assert is asking for trouble. Compile with NDEBUG set and the effects mysteriously disappear! Anything beyond an equality expression or straight boolean should be avoided.


Replies

usrnmtoday at 5:49 PM

I once spent several days debugging that same mistake. Stuff worked perfectly in tests but broke misteriously in production builds. Couldn't stop laughing for a few minutes when I finally figured it out.

maccardtoday at 6:45 PM

Indeed.

   bool is_even(int* valPtr) {
      assert(valPtr != nullptr);
      return *valPtr % 2;
    }
Does not do what you think it does with nullptr. A major game engine [0] has a toggle to enable asserts in shipping builds, mostly for this reason

[0] https://dev.epicgames.com/documentation/en-us/unreal-engine/...

show 3 replies
samivtoday at 7:02 PM

That's why you define your own assert macro and keep in on unconditionally. Your programs will be better for it.

show 1 reply
nyc_pizzadevtoday at 4:49 PM

This is just a symptom of a bad assert() implementation, which funny enough is the standard. If you properly (void) it out, side effects are maintained.

https://github.com/fiberfs/fiberfs/blob/7e79eaabbb180b0f1a79...

show 1 reply
jmalickitoday at 4:59 PM

Side effects are bad of course, but anything beyond a straight boolean or equality is bad?

`assert(vector.size() < 3)` is ridiculous to you?

nealabqtoday at 5:46 PM

I don't mean to be that guy, but for "functional" programmers a print statement has "side effects".

But your meaning is clear. In an assert expression, don't call functions that might change the program/database state. Be as "const" as possible.

show 1 reply