Expanding the Image API

Disabling Error Checks in Release Builds

Why might we want to disable error checking in release builds? Isn't it always important?

Abstract art representing computer programming

Error checking is indeed important, but there are good reasons to consider disabling some checks in release builds. Let's explore why:

Performance Considerations

The primary reason for disabling error checks in release builds is performance. Error checking often involves additional comparisons, function calls, or conditional branches.

While these operations are typically fast, they can add up in performance-critical sections of code that are executed frequently.

For example, consider our Render() function:

void Image::Render(SDL_Surface* Surface) {
#ifdef DEBUG
  int InitialWidth = mAppliedDestRectangle.w;
  int InitialHeight = mAppliedDestRectangle.h;
#endif

  if (mScalingMode == ScalingMode::None) {
    SDL_BlitSurface(
      mImageSurface, &mAppliedSrcRectangle,
      Surface, &mAppliedDestRectangle);
  } else {
    SDL_BlitScaled(
      mImageSurface, &mAppliedSrcRectangle,
      Surface, &mAppliedDestRectangle);
  }

#ifdef DEBUG
  if (InitialWidth != mAppliedDestRectangle.w) {
    std::cout << "Horizontal clipping\n";
  }
  if (InitialHeight != mAppliedDestRectangle.h) {
    std::cout << "Vertical clipping\n";
  }
#endif
}

This function might be called many times per frame in a game. The debug checks, while useful during development, add overhead that isn't necessary in a well-tested release build.

Assumption of Correctness

In release builds, we often assume that our code has been thoroughly tested and that these checks are no longer necessary. This assumption allows us to optimize for the common case where errors don't occur.

Balancing Act

It's important to note that we're not advocating for removing all error checks. Critical checks that prevent crashes or data corruption should remain. The key is to find a balance between safety and performance.

Implementation Strategies

We can use preprocessor directives to selectively include or exclude error checks:

void Image::SetSourceRectangle(
  const SDL_Rect& Rect
) {
  mRequestedSrcRectangle = Rect;
#ifdef DEBUG
  if (!ValidateRectangle(
    Rect, mImageSurface, "Source Rectangle"
  )) {
    std::cout << "Invalid source rectangle, "
      "using default\n";
  }
#endif
  mAppliedSrcRectangle = ValidateRectangle(
    Rect, mImageSurface, "Source Rectangle"
  ) ? Rect : SDL_Rect{
    0, 0, mImageSurface->w, mImageSurface->h
  };
}

In this example, we keep the validation logic but only output debug information in debug builds.

Remember, the goal is to create a robust application that performs well. Use error checking judiciously, and consider the context of your application when deciding which checks to keep in release builds.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 51 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved