logoalt Hacker News

MontagFTByesterday at 4:23 PM9 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

bluGillyesterday at 9:53 PM

Related our logging system has a debug which is not logged by default but can be turned on if a problem in an area is found (in addition to the normal error/info which is logged). I had the idea that if a test fails we should print all these debugs - easy enough to turn on but a number of tests failed because of side effects that didn't show up when off.

i'm trying to think of how/if we can run tests with all logging off to find the error and info logs with side effects.

usrnmyesterday 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.

maccardyesterday 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 4 replies
saagarjhatoday at 12:36 AM

I actually feel like asserts ended up in the worst situation here. They let you do one line quick checks which get compiled out which makes them very tempting for those but also incredibly frustrating for more complex real checks you’d want to run in debug builds but not in release.

samivyesterday 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_pizzadevyesterday 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
jmalickiyesterday 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?

andrepdyesterday at 9:14 PM

Rust has assert and debug_assert, which are self-explanatory. But it also has an assert_unchecked, which is what other languages incl C++ call an "assume" (meaning "this condition not holding is undefined behaviour"), with the added bonus that debug builds assert that the condition is true.

nealabqyesterday 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