Earlier quoted context omitted.
No, the code that does this is always active
Shouldn't control flow diverge if the assert is triggered when NDEBUG is not defined? Pretty sure assert is defined to call abort when triggered and that is tagged [[noreturn]].
C++26: A User-Friednly assert() macro
71–80 of 89 posts
Re: C++26: A User-Friednly assert() macro
#72Earlier 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.
But if the assertion fails, the program is aborted before the pointer would have been dereferenced, making it not UB. This explanation is bogus.
Re: C++26: A User-Friednly assert() macro
#73Earlier quoted context omitted.
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
#74Earlier quoted context omitted.
There's nothing wrong with it. It does exactly what you think it does when passed null.
A lot of compilers will optimize out a NULL pointer check because dereferencing a NULL pointer is UB. Because assert will not run the following code in the case of a NULL pointer, AFAIK this exact code is still defined behavior, but if for some reason some code dereferenced the NULL pointer before, it would be optimized out - there are some corner cases that aren't obvious on the surface. This kind of thing was alway…
The issue is cause by C declaring that dereferencing a null pointer is UB. It's not really an issue with assertions.
You can get the same optimisation-removes-code for any UB.
Re: C++26: A User-Friednly assert() macro
#75D just makes assert() part of the language: https://dlang.org/spec/expression.html#assert_expressions The behavior of it can be set with a compiler switch to one of: 1. Immediately halting via execution of a special CPU instruction 2. Aborting the program 3. Calling the assert failure function in the corresponding C runtime library 4. Throwing the AssertError exception in the D runtime library So there's no issue wit…
Our idea of declare (optimize (speed 3) (safety 0))
Re: C++26: A User-Friednly assert() macro
#76Putting 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.
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.
Necessarily, in any language, you should not optimise until you have measured a performance problem. Do not write this because "I think it's faster". Either you measured, and you know it's crucial to your desired performance, or you didn't measure and you are wasting everybody's time. If you just scatter such hints in your code because "I think it's faster" and you're wrong about it being true the program has UB, if you're wrong about it being faster the program may be slower or just harder to maintain.
Re: C++26: A User-Friednly assert() macro
#77"C++47: Finally, a Standard Way to Split a String by Delimiter"
std::vector split(const std::string& text, char delimiter) {
std::vector parts;
std::istringstream stream(text);
std::string part;
while (std::getline(stream, part, delimiter)) {
parts.push_back(part);
}
return parts;
}Re: C++26: A User-Friednly assert() macro
#78Earlier quoted context omitted.
A lot of compilers will optimize out a NULL pointer check because dereferencing a NULL pointer is UB. Because assert will not run the following code in the case of a NULL pointer, AFAIK this exact code is still defined behavior, but if for some reason some code dereferenced the NULL pointer before, it would be optimized out - there are some corner cases that aren't obvious on the surface. This kind of thing was alway…
Sure, but none of that is relevant to just the code snippet that was posted. The compiler can exploit UB in other code to do weird things, but that's just C being C. There's nothing unexpected in the snippet posted. The issue is cause by C declaring that dereferencing a null pointer is UB. It's not really an issue with assertions. You can get the same optimisation-removes-code for any UB.
> The issue is cause by C declaring that dereferencing a null pointer is UB. It's not really an issue with assertions. > You can get the same optimisation-removes-code for any UB.
I disagree - It’s a 4 line toy example but in a 30-40 line function these things are not always clear. The actual problem is if you compile with NDEBUG=1, the nullptr check is removed and the optimiser can (and will, currently) do unexpected things.
The printf sample above is a good example of the side effects.
Re: C++26: A User-Friednly assert() macro
#79Earlier quoted context omitted.
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()`?
No, Rust is the same as C++ in terms of tracking side effects. It doesn't matter that there are no parameters. It could manipulate globals or call other functions that have side effects (e.g. printing).
Re: C++26: A User-Friednly assert() macro
#80Earlier quoted context omitted.
No, Rust is the same as C++ in terms of tracking side effects. It doesn't matter that there are no parameters. It could manipulate globals or call other functions that have side effects (e.g. printing).
What about rust const fn() ? I think it guarantees there are no side effects