Comment by 20k
4 days ago
Its pretty easy for me to guarantee that my asserts will all always be run via NDEBUG. I can't make that same guarantee for contracts
4 days ago
Its pretty easy for me to guarantee that my asserts will all always be run via NDEBUG. I can't make that same guarantee for contracts
> Its pretty easy for me to guarantee that my asserts will all always be run via NDEBUG.
That's the opposite of what NDEBUG does. https://en.cppreference.com/cpp/error/assert
Critical bit:
> 1) If NDEBUG is defined as a macro name at the point in the source code where <cassert> or <assert.h> is included, the assertion is disabled: assert does nothing.
It also is impossible to guarantee it unless you're the only one compiling the program. If you've built a library that others can build and relied on asserts executing for your library to be correct, you wrote a bad library.
EDIT: Neither asserts nor these C++26 contract features should be used in a way that requires that they be executed. If you do, you're using them wrong because it is valid for someone to disable them as runtime checks. If the code must run, you should use some other mechanism, I'd recommend an if statement.
Of course? You simply undefine NDEBUG in your library
Its trivially easy to guarantee that an assert always runs, and its well defined behaviour according to the spec. There's no reason not to if you want to use asserts in a way that guarantees that they always fire, which is a supported use case. Its common practice
There's no equivalent for contracts
> Of course?
You sound as if "my asserts will all always be run via NDEBUG" makes perfect sense and not the exact opposite of what you've expanded it to
> Its common practice
not really, no
post ++11 cpp has been moving away from preprocessor (pedagogically and culturally), so "let's force-undefine NDEBUG" trick isn't at the top of most people's minds
1 reply →
No, it's not. Don't do that. Someone (like me) will replace assert.h wholesale and it will not behave the way you expected. Always define your own internal macro and always provide facilities for the user to override it.
10 replies →
I don't know if it's good practice but I replace assert and assert.h with my own code (you just have to make sure to make the necessary platform specific calls in your replacement headers). So I always know exactly how assert will behave in my own codebase even when invoked by a library.
It's worth noting that the motivation for the above was poorly written libraries that hardcode the use of the builtin assert. So I agree with you completely on that point.
That said I've never been particularly impressed with how assert is defined by the standard and now somehow contracts appear set to be even worse.
Now you know. It's VERY bad practice.
2 replies →