Live data from Hacker News

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

sandordargo.com

21–30 of 89 posts

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

#21

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.

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

#22
post #21

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.

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

#23
post #11

Shouldn't the preprocessor be fixed, if it trips that easily on common C++ constructs?

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

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.

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

#24

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.

That's why you define your own assert macro and keep in on unconditionally. Your programs will be better for it.

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

#25
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/...

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.

There's nothing wrong with it. It does exactly what you think it does when passed null.

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

#26
post #24

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.

That's why you define your own assert macro and keep in on unconditionally. Your programs will be better for it.

An assertion can be arbitrarily expensive to evaluate. This may be worth the cost in a debug build but not in a release build. If all of assertions are cheap, they likely are not checking nearly as much as they could or should.

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

#27
post #16
post #4

> (assert) doesn't follow the usual SCREAMING_SNAKE_CASE convention we associate with macros 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.

In C++ you should probably #include instead of unless you have a good reason. And especially avoid #including both. provides the function std::getc(..) while 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…

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

Yeah, this is still in windows.h unless you #define NOMINMAX

I remember having to guard against this in some inline code by surrounding the c++ calls with parenthesis, eg `(std::min)(a, b)`

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

#28
post #24

Earlier quoted context omitted.

That's why you define your own assert macro and keep in on unconditionally. Your programs will be better for it.

An assertion can be arbitrarily expensive to evaluate. This may be worth the cost in a debug build but not in a release build. If all of assertions are cheap, they likely are not checking nearly as much as they could or should.

Possibly but I've never seen it in practice that some assert evaluation would be the first thing to optimize. Anyway should that happen then consider removing just that assert.

That being said being slow or fast is kinda moot point if the program is not correct. So my advisor to leave always all asserts in. Offensive programming.

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

#30
post #16
post #4

> (assert) doesn't follow the usual SCREAMING_SNAKE_CASE convention we associate with macros 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.

In C++ you should probably #include instead of unless you have a good reason. And especially avoid #including both. provides the function std::getc(..) while 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…

[deleted]
Post reply on HN