Live data from Hacker News

C++26: A User-Friednly assert() macro

sandordargo.com

51–60 of 89 posts

Re: C++26: A User-Friednly assert() macro

#51

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

You're right, thanks!

This works too (but I wouldn't recommend it):

   assert( someBooleanExpression || ! "It is false" );

Re: C++26: A User-Friednly assert() macro

#52
post #37

Earlier quoted context omitted.

If your assert compiles down to `if (condition) {}` in production then the compiler will optimize away the condition while keeping any side effects.

Yeah which may not be what you want. E.g. `assert(expensive_to_compute() == 0)`. The correct way to solve this is with debug asserts (as in Rust, or how the parent described).

Genuine question, does Rust know if `expensive_to_compute()` has side effects? There are no params, so could it be compiled out if the return value is ignored? Ex: `expensive_to_compute()` What about: `(void) expensive_to_compute()`?

Re: C++26: A User-Friednly assert() macro

#53
post #21

Earlier 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/...

Let's not vague post on HN. What's the problem with the above?

The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. This means it is legal to optimize out any code paths that rely on this, even if they occur earlier in program order.

Re: C++26: A User-Friednly assert() macro

#54

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.

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.

Re: C++26: A User-Friednly assert() macro

#55

Earlier quoted context omitted.

A standard way to split a string? Well, what's wrong with: std::views::split(my_string, delimeter) ?

Template bloat, terrible compile errors, terrible debug build performance, 1 second of extra compile time per cpp file when you include ranges, and you can't step through it in a debugger.

> you can't step through it in a debugger.

What do you mean by that?

Re: C++26: A User-Friednly assert() macro

#56

Earlier quoted context omitted.

Let's not vague post on HN. What's the problem with the above?

The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. This means it is legal to optimize out any code paths that rely on this, even if they occur earlier in program order.

> The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer.

Only when NDEBUG is defined, right?

Re: C++26: A User-Friednly assert() macro

#57

Earlier quoted context omitted.

The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. This means it is legal to optimize out any code paths that rely on this, even if they occur earlier in program order.

> The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. Only when NDEBUG is defined, right?

No, the code that does this is always active

Re: C++26: A User-Friednly assert() macro

#59

Earlier quoted context omitted.

> The problem is the code unconditionally dereferences the pointer, which would be UB if it was a null pointer. Only when NDEBUG is defined, right?

No, the code that does this is always active

Right so strictly speaking C++ could do anything here when passed a null pointer, because even though assert terminates the program, the C++ compiler cannot see that, and there is then undefined behaviour in that case

Re: C++26: A User-Friednly assert() macro

#60

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

[deleted]
Post reply on HN