Intermediate Gotchas
The Assertion That Did Work
the counter that vanishes in a release build
int main() {
int retries = 0;
assert(++retries == 1);
std::cout << "retries: " << retries << '\n';
}
Build it normally, then with -DNDEBUG. What does it print?
Answer
Normal build:
With -DNDEBUG:
The assertion's test is not merely disabled; it is never evaluated.
Why¶
assert is a macro for checking an invariant, not a place to do work. When NDEBUG is
defined before <cassert>, its expansion does not evaluate the operand, so ++retries
disappears completely. Both GCC 11.5 builds were quiet under -Wall -Wextra. Separate
the effect that must happen from the condition that should be checked.
The fix¶
Takeaway: never put a side effect inside assert; a release build may erase it.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo