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.
C++26: A User-Friednly assert() macro
41–50 of 89 posts
Re: C++26: A User-Friednly assert() macro
#42> assert(x > 0 && "x was not greater than zero"); Shouldn't that be "||" rather than "&&"? We want the message only if the boolean expression is false.
Re: C++26: A User-Friednly assert() macro
#43Earlier quoted context omitted.
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.
Not just for functional programmers. Prints and other I/O operations absolutely are side effects. That's not running counter to the point being made. Print in an assert and NDEBUG takes away that behavior.
Re: C++26: A User-Friednly assert() macro
#44Putting 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.
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.
Re: C++26: A User-Friednly assert() macro
#45Earlier quoted context omitted.
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/...
I'm sorry, but what exactly is the problem with the code? I've been staring at it for quite a while now and still don't see what is counterintuitive about it.
Re: C++26: A User-Friednly assert() macro
#46> assert(x > 0 && "x was not greater than zero"); Shouldn't that be "||" rather than "&&"? We want the message only if the boolean expression is false.
No, because the string will be implicitly converted to `true` and `(a && true) == a` (for boolean `a`), so it will only be `false` if the assertion fails. Using || would always evaluate to `true`
Re: C++26: A User-Friednly assert() macro
#47Putting 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.
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/...
Re: C++26: A User-Friednly assert() macro
#48Earlier quoted context omitted.
I'm sorry, but what exactly is the problem with the code? I've been staring at it for quite a while now and still don't see what is counterintuitive about it.
Depends on where you're coming from, but some people would expect it to enforce that the pointer is non-null, then proceed. Which would actually give you a guaranteed crash in case it is null. But that's not what it does in C++, and I could see it not being entirely obvious.
Re: C++26: A User-Friednly assert() macro
#49Earlier quoted context omitted.
assert() is meant to be compiled away if NDEBUG is defined, otherwise it shouldn't be called assert(). Given that assert() may be compiled away, it makes sense not to give it anything that has side effects. Abseil has the convention where instead of assert(), users call "CHECK" for checks that are guaranteed to happen at run time, or "DCHECK" for checks that will be compiled away when NDEBUG is defined. https://githu…
If your assert compiles down to `if (condition) {}` in production then the compiler will optimize away the condition while keeping any side effects.
The correct way to solve this is with debug asserts (as in Rust, or how the parent described).
Re: C++26: A User-Friednly assert() macro
#50Earlier quoted context omitted.
Depends on where you're coming from, but some people would expect it to enforce that the pointer is non-null, then proceed. Which would actually give you a guaranteed crash in case it is null. But that's not what it does in C++, and I could see it not being entirely obvious.
Assert doesn't work like that in any language.
But yes, “assert” in most languages is debug-only.