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'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.
IshKebab 10 minutes ago [-]
There's nothing wrong with it. It does exactly what you think it does when passed null.
samiv 20 minutes ago [-]
That's why you define your own assert macro and keep in on unconditionally. Your programs will be better for it.
usrnm 2 hours ago [-]
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.
nyc_pizzadev 3 hours ago [-]
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.
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.
Side effects are bad of course, but anything beyond a straight boolean or equality is bad?
`assert(vector.size() < 3)` is ridiculous to you?
nealabq 2 hours ago [-]
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.
toxik 50 minutes ago [-]
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.
omoikane 3 hours ago [-]
> (assert) doesn't follow the usual SCREAMING_SNAKE_CASE convention we associate with macros
In C++ you should probably #include <cstdio> instead of <stdio.h> unless you have a good reason. And especially avoid #including both. <cstdio> provides the function std::getc(..) while <stdio.h> usually provides getc(..) as a macro.
htons(..) and related socket-utility names are also often macros, but I'm pretty sure there is not a std::htons(..) in the C++ standard, partly because 'htons' is not an attractive name. Since it's (sometimes) a macro don't qualify its namespace like ::htons(..).
A long time ago in the Microsoft C (and later C++) dev envs there were macros named "min" and "max", which I thought were terrible names for macros.
nyc_pizzadev 4 hours ago [-]
The nice thing about assert() is you can just define your own:
In this case, the ability to see the actual values that triggered the assert is way more helpful.
BoingBoomTschak 2 hours ago [-]
Yeah, but the macro system being so pitiful makes me long for one that allows something as magical as fiveam's is (https://github.com/lispci/fiveam/blob/e43d6c8e7da5a80d5c33e8...) instead of having to write special cases for unary and binary predicates.
grokcodec 2 hours ago [-]
Friedns shouldn't let Freidns post on HN without running spell check
amelius 2 hours ago [-]
Shouldn't the preprocessor be fixed, if it trips that easily on common C++ constructs?
marginalia_nu 2 hours ago [-]
Preprocessor is just doing text transformations on the sources.
It's not really something that can be fixed, other than moving away from the preprocessor and putting metaprogramming capabilities into the language itself (which C++ has been doing).
amelius 22 minutes ago [-]
I mean, you could extend it such that a simple comma has no special meaning.
But I agree, fewer special tricks is better and that includes the preprocessor.
tom_ 2 hours ago [-]
I'm sure the standardization committee are always looking for fresh ideas!
3 days ago [-]
semiinfinitely 2 hours ago [-]
"C++47: Finally, a Standard Way to Split a String by Delimiter"
porise 58 minutes ago [-]
I'm still waiting for C++ to support Unicode properly.
throwpoaster 2 hours ago [-]
assert(spellcheck(“Friednly”));
Rendered at 19:22:30 GMT+0000 (Coordinated Universal Time) with Vercel.
[0] https://dev.epicgames.com/documentation/en-us/unreal-engine/...
https://github.com/fiberfs/fiberfs/blob/7e79eaabbb180b0f1a79...
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://github.com/abseil/abseil-cpp/blob/0093ac6cac892086a6...
https://github.com/abseil/abseil-cpp/blob/0093ac6cac892086a6...
`assert(vector.size() < 3)` is ridiculous to you?
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.
There are a few things like that, for example:
https://en.cppreference.com/w/c/numeric/math/isnan - isnan is an implementation defined macro.
https://en.cppreference.com/w/c/io/fgetc - `getc` may be implemented as a macro, but often it's a function.
htons(..) and related socket-utility names are also often macros, but I'm pretty sure there is not a std::htons(..) in the C++ standard, partly because 'htons' is not an attractive name. Since it's (sometimes) a macro don't qualify its namespace like ::htons(..).
A long time ago in the Microsoft C (and later C++) dev envs there were macros named "min" and "max", which I thought were terrible names for macros.
https://github.com/fiberfs/fiberfs/blob/7e79eaabbb180b0f1a79...
In this case, the ability to see the actual values that triggered the assert is way more helpful.
It's not really something that can be fixed, other than moving away from the preprocessor and putting metaprogramming capabilities into the language itself (which C++ has been doing).
But I agree, fewer special tricks is better and that includes the preprocessor.