Production and Debug Builds
FAQ
-
What is the value of using
BOOST_ASSERTorBOOST_STATIC_ASSERTover the Standard Library assert macros?There are a few advantages of using the Boost asserts, available in
<boost/assert.hpp>, including thatBOOST_ASSERTis fully customizable usingBOOST_ENABLE_ASSERT_HANDLER, which can be used to log extra data or stack traces, and there is better integration with Boost.Test.BOOST_STATIC_ASSERTis best utilized when using older C++ standards (pre-C++17), or you are using deeply templated code. You might also prefer the Boost macros if you are engaging the features of other Boost libraries and are looking for consistent tooling. For a fuller discussion, refer to Boost Macros. -
For maximum performance, is it good practice to remove, or comment out, the `BOOST_ASSERT`s for the final production code, or do they simply not get compiled into anything so there is no performance cost for leaving them as is?
By default,
BOOST_ASSERTmacros are completely removed from the compiled binary whenNDEBUGis defined, just like the standard assert macro. IfNDEBUGis not defined aBOOST_ASSERT(x)will expand, usually to anassertion_failed()if the assert condition fails. If NDEBUG is defined it expands to((void)0)so nothing is generated. Boost does provide theBOOST_DISABLE_ASSERTSmacro, which has the same effect on Boost asserts asNDEBUG- but will leave other asserts alone. -
What is usually considered to be best practices in handling assertions that fire with a production build?
Instead of throwing an exception when an assert fails, it is often the best practice to log the failure. For example, here is a custom assert handler using the features of Boost.Log to record the event:
#include <boost/assert.hpp> #include <boost/log/trivial.hpp> #include <boost/log/utility/setup/file.hpp> #include <boost/log/utility/setup/console.hpp> #include <boost/log/utility/setup/common_attributes.hpp> #include <boost/log/expressions.hpp> #include <sstream> #include <cstdlib> namespace logging = boost::log; // Configure Boost.Log (call once at startup) void init_logging() { logging::add_common_attributes(); // Console output logging::add_console_log( std::clog, logging::keywords::format = "[%TimeStamp%] [%Severity%] %Message%" ); // File output logging::add_file_log( logging::keywords::file_name = "assert_failures_%N.log", logging::keywords::rotation_size = 10 * 1024 * 1024, // 10 MB logging::keywords::format = "[%TimeStamp%] [%Severity%] %Message%" ); } // Custom handler for BOOST_ASSERT namespace boost { void assertion_failed(char const* expr, char const* function, char const* file, long line) { std::ostringstream oss; oss << "BOOST_ASSERT failed!\n" << " Expression: " << expr << "\n" << " Function: " << function << "\n" << " File: " << file << "\n" << " Line: " << line; BOOST_LOG_TRIVIAL(error) << oss.str(); std::abort(); // Optional: comment out if soft fail is desired } }An example use of this handler would be:
#include <boost/assert.hpp> #include <iostream> // Declare logging initializer void init_logging(); void test_logic(int value) { BOOST_ASSERT(value >= 0); std::cout << "Value is: " << value << std::endl; } int main() { init_logging(); std::cout << "Testing BOOST_ASSERT with value = 42..." << std::endl; test_logic(42); std::cout << "Testing BOOST_ASSERT with value = -1..." << std::endl; test_logic(-1); // Logs to file and console, then aborts return 0; } -
What should I be aware of when moving from a Debug to a Production release?
Use this checklist to ensure your application correctly integrates Boost libraries across Debug and Release configurations.
-
Linking and Compatibility
-
Link with the correct Boost library variant (
-gdfor Debug, none for Release). -
Ensure runtime settings (Debug CRT or Release CRT) match Boost binaries.
-
Avoid mixing Debug-built Boost libraries with Release-built applications.
-
Macro Definitions and Configuration
-
Define
BOOST_DEBUGin Debug builds to enable extra runtime checks (if applicable). -
Define
BOOST_DISABLE_ASSERTSin Release builds to removeBOOST_ASSERTchecks. -
Optionally define
BOOST_ENABLE_ASSERT_HANDLERto install custom assertion handlers. -
Review conditional macros like
BOOST_NO_EXCEPTIONS,BOOST_NO_RTTI, etc. -
Assertions and Diagnostics
-
Use
BOOST_ASSERTfor critical development-time checks. -
Consider diagnostic logging using
BOOST_LOG_TRIVIAL. -
Ensure failing assertions are tested and logged in Debug builds.
-
Debugging and Tooling
-
Run AddressSanitizer, Valgrind, or Visual Leak Detector in Debug builds. Refer to Contributor Guide: Sanitizers.
-
Confirm Boost.Pool, Boost.Container, and alloc-heavy libraries don’t leak memory.
-
Validate Boost.Thread, Boost.Asio, and Boost.Fiber components using thread sanitizers.
-
Performance Awareness
-
Avoid benchmarking with Debug builds — optimization is disabled.
-
Use Release builds to test compile times for Boost.Mp11, Boost.Spirit, and any heavy use of templates.
-
Validate any
BOOST_FORCEINLINEorBOOST_NOINLINEeffects in both builds. -
Unit Testing
-
Run the full suite of unit tests in both Debug and Release.
-
Ensure no logic is only covered by Debug-only paths or assertions.
-
Use Boost.Test to validate results across optimization levels.
-
-
Typically, how should I set up a CMake file to handle Debug and Release builds?
Here’s an example of how to set up your
CMakeLists.txtto handleBOOST_ASSERTcorrectly by toggling behavior based on the build type (Debug or Release). The example includes linking with some sample libraries (Boost.Log, Boost.System and Boost.Thread):cmake_minimum_required(VERSION 3.10) project(MyBoostApp) # Set your C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Enable debug symbols for Debug mode set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # Link Boost (adjust components as needed) find_package(Boost REQUIRED COMPONENTS log log_setup system thread) target_link_libraries(MyBoostApp PRIVATE Boost::log Boost::log_setup Boost::system Boost::thread ) add_executable(MyBoostApp main.cpp) target_include_directories(MyBoostApp PRIVATE ${Boost_INCLUDE_DIRS}) target_link_libraries(MyBoostApp PRIVATE ${Boost_LIBRARIES}) # Enable BOOST_ASSERT in Debug, disable in Release target_compile_definitions(MyBoostApp PRIVATE $<$<CONFIG:Debug>:BOOST_ENABLE_ASSERT_HANDLER> $<$<CONFIG:Release>:NDEBUG> ) # Optional: You can define a custom assert handler in debug builds # by linking a file like the assert handler shown above that defines `boost::assertion_failed`