Using Assert in Release Builds

The lesson mentions that assert() calls are sometimes stripped out in release builds for performance. What if I want to keep some critical assertions enabled in release builds?

There are a few ways to keep certain assert() calls active in release builds:

Option 1: Rather than defining the global NDEBUG macro disable assert() calls, we can implement our own conventions. For example, we could use #ifdef directives with macros that have names like ENABLE_ASSERTIONS and ENABLE_RELEASE_ASSERTIONS:

#include <cassert>

int Divide(int x, int y) {
#ifdef ENABLE_RELEASE_ASSERTIONS
  assert(y != 0 && "Cannot divide by zero");
#endif
  return x / y;
}

We then have more granular control over which assertions are enabled, based on which definitions we provide in our project settings

Option 2: Create a custom assert-like macro that isn't disabled in release builds. In the following example, our RELEASE_ASSERT() macro will be used whether or not NDEBUG is defined:

#include <iostream>

#define RELEASE_ASSERT(expr)                 \
  if (!(expr)) {                             \
    std::cerr << "Assertion failed: " #expr; \
    abort();                                 \
  }

int Divide(int x, int y) {
  RELEASE_ASSERT(y != 0);  
  return x / y;
}

int main() {
  Divide(2, 0);
}
Assertion failed: y != 0

Option 3: Use logging libraries like spdlog or Boost.Log that offer assertion-like checks which remain enabled in release builds by default.

In general, the decision to keep assertions enabled in release builds is a tradeoff between performance and catching/logging critical errors. Enable them selectively for the most crucial checks.

Errors and Assertions

Learn how we can ensure that our application is in a valid state using compile-time and run-time assertions.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Using static_assert with Non-constexpr Expressions
Can static_assert() be used with expressions that are not known at compile-time, such as values read from a file or user input?
Avoiding Side Effects in Assertions
Is it okay to use assert() with expressions that have side effects, like assert(++x > 0)? Or should assertions be side-effect free?
Assertions vs Exceptions
When should I use assertions vs throwing exceptions? They seem to serve similar purposes.
Defensive Programming with Assertions
How can I use assertions to practice "defensive programming" and make my code more robust?
Using static_assert in Template Code
The lesson shows an example of using static_assert() with std::is_floating_point to validate template parameters. What are some other common type traits I can use for template validation?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant