Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

The Boost.Assert library provides several configurable diagnostic macros similar in behavior and purpose to the standard macro assert from <cassert>.

Assertion Macros, <boost/assert.hpp>

BOOST_ASSERT

The header <boost/assert.hpp> defines the macro BOOST_ASSERT, which is similar to the standard assert macro defined in <cassert>. The macro is intended to be used in both Boost libraries and user code.

  • By default, BOOST_ASSERT(expr) expands to assert(expr).

  • If the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> is included, BOOST_ASSERT(expr) expands to ((void)0), regardless of whether the macro NDEBUG is defined. This allows users to selectively disable BOOST_ASSERT without affecting the definition of the standard assert.

  • If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> is included, BOOST_ASSERT(expr) expands to

    (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr,
        BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

    That is, it evaluates expr and if it’s false, calls ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__). This is true regardless of whether NDEBUG is defined.

    boost::assertion_failed is declared in <boost/assert.hpp> as

    namespace boost
    {
        void assertion_failed(char const * expr, char const * function,
            char const * file, long line);
    }

    but it is never defined. The user is expected to supply an appropriate definition.

  • If the macro BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined when <boost/assert.hpp> is included, BOOST_ASSERT(expr) expands to ((void)0) when NDEBUG is defined. Otherwise the behavior is as if BOOST_ENABLE_ASSERT_HANDLER has been defined.

As is the case with <cassert>, <boost/assert.hpp> can be included multiple times in a single translation unit. BOOST_ASSERT will be redefined each time as specified above.

BOOST_ASSERT_MSG

The macro BOOST_ASSERT_MSG is similar to BOOST_ASSERT, but it takes an additional argument, a character literal, supplying an error message.

  • By default, BOOST_ASSERT_MSG(expr,msg) expands to assert((expr)&&(msg)).

  • If the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> is included, BOOST_ASSERT_MSG(expr,msg) expands to ((void)0), regardless of whether the macro NDEBUG is defined.

  • If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> is included, BOOST_ASSERT_MSG(expr,msg) expands to

    (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr,
        msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

    This is true regardless of whether NDEBUG is defined.

    boost::assertion_failed_msg is declared in <boost/assert.hpp> as

    namespace boost
    {
        void assertion_failed_msg(char const * expr, char const * msg,
            char const * function, char const * file, long line);
    }

    but it is never defined. The user is expected to supply an appropriate definition.

  • If the macro BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined when <boost/assert.hpp> is included, BOOST_ASSERT_MSG(expr) expands to ((void)0) when NDEBUG is defined. Otherwise the behavior is as if BOOST_ENABLE_ASSERT_HANDLER has been defined.

As is the case with <cassert>, <boost/assert.hpp> can be included multiple times in a single translation unit. BOOST_ASSERT_MSG will be redefined each time as specified above.

BOOST_VERIFY

The macro BOOST_VERIFY has the same behavior as BOOST_ASSERT, except that the expression that is passed to BOOST_VERIFY is always evaluated. This is useful when the asserted expression has desirable side effects; it can also help suppress warnings about unused variables when the only use of the variable is inside an assertion.

  • If the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> is included, BOOST_VERIFY(expr) expands to ((void)(expr)).

  • If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> is included, BOOST_VERIFY(expr) expands to BOOST_ASSERT(expr).

  • Otherwise, BOOST_VERIFY(expr) expands to ((void)(expr)) when NDEBUG is defined, to BOOST_ASSERT(expr) when it’s not.

BOOST_VERIFY_MSG

The macro BOOST_VERIFY_MSG is similar to BOOST_VERIFY, with an additional parameter, an error message.

  • If the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> is included, BOOST_VERIFY_MSG(expr,msg) expands to ((void)(expr)).

  • If the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> is included, BOOST_VERIFY_MSG(expr,msg) expands to BOOST_ASSERT_MSG(expr,msg).

  • Otherwise, BOOST_VERIFY_MSG(expr,msg) expands to ((void)(expr)) when NDEBUG is defined, to BOOST_ASSERT_MSG(expr,msg) when it’s not.

BOOST_ASSERT_IS_VOID

The macro BOOST_ASSERT_IS_VOID is defined when BOOST_ASSERT and BOOST_ASSERT_MSG are expanded to ((void)0). Its purpose is to avoid compiling and potentially running code that is only intended to prepare data to be used in the assertion.

void MyContainer::erase(iterator i)
{
// Some sanity checks, data must be ordered
#ifndef BOOST_ASSERT_IS_VOID

    if(i != c.begin()) {
        iterator prev = i;
        --prev;
        BOOST_ASSERT(*prev < *i);
    }
    else if(i != c.end()) {
        iterator next = i;
        ++next;
        BOOST_ASSERT(*i < *next);
    }

#endif

    this->erase_impl(i);
}
  • By default, BOOST_ASSERT_IS_VOID is defined if NDEBUG is defined.

  • If the macro BOOST_DISABLE_ASSERTS is defined, BOOST_ASSERT_IS_VOID is always defined.

  • If the macro BOOST_ENABLE_ASSERT_HANDLER is defined, BOOST_ASSERT_IS_VOID is never defined.

  • If the macro BOOST_ENABLE_ASSERT_DEBUG_HANDLER is defined, then BOOST_ASSERT_IS_VOID is defined when NDEBUG is defined.

Current Function Macro, <boost/current_function.hpp>

BOOST_CURRENT_FUNCTION

The header <boost/current_function.hpp> defines a single macro, BOOST_CURRENT_FUNCTION, similar to the C99 predefined identifier __func__.

BOOST_CURRENT_FUNCTION expands to either a string literal, or the name of a character array local to the current function, containing the (fully qualified, if possible) name of the enclosing function. If there is no enclosing function, the behavior varies by compiler, but is usually a compile error.

Some compilers do not provide a way to obtain the name of the current enclosing function. On such compilers, or when the macro BOOST_DISABLE_CURRENT_FUNCTION is defined, BOOST_CURRENT_FUNCTION expands to "(unknown)".

BOOST_DISABLE_CURRENT_FUNCTION addresses a use case in which the programmer wishes to eliminate the string literals produced by BOOST_CURRENT_FUNCTION from the final executable for security reasons.

Source Location Support, <boost/assert/source_location.hpp>

Description

The header <boost/assert/source_location.hpp> defines source_location, a class representing a source location and containing file, line, function and column information. It’s similar to std::source_location from C++20, but only requires C++03.

The macro BOOST_CURRENT_LOCATION creates a source_location object containing information about the current source location. It can be used roughly in the same way std::source_location::current() can be used, such as in the declaration of a function default argument:

#include <boost/assert/source_location.hpp>
#include <iostream>

void f( boost::source_location const& loc = BOOST_CURRENT_LOCATION )
{
    std::cout << "f() called from: " << loc << std::endl;
}

int main()
{
    f();
}

The output of this example varies by compiler and C++ standard level, but it’s generally one of

f() called from: example.cpp:11:6 in function 'int main()'
f() called from: example.cpp:11:5 in function 'main'
f() called from: example.cpp:11 in function 'main'
f() called from: example.cpp:4

This is useful if, for example, you want to declare a function that throws an exception, such that the source location of the caller is attached to the thrown exception:

BOOST_NORETURN BOOST_NOINLINE void throw_invalid_argument(
    char const* message,
    boost::source_location const& loc = BOOST_CURRENT_LOCATION )
{
    boost::throw_exception( std::invalid_argument( message ), loc );
}

Now you could use this helper function in, say, the implementation of at to signal an index that is out of range:

T& my_class::at( size_t i )
{
    if( i >= size() ) throw_invalid_argument( "index out of range" );
    return data()[ i ];
}

This would attach the source location of the line in at that calls throw_invalid_argument to the thrown exception.

Note that if instead you use BOOST_THROW_EXCEPTION in throw_invalid_argument, the location will be that of throw_invalid_argument and not of its caller.

Synopsis

namespace boost
{

struct source_location
{
    constexpr source_location() noexcept;
    constexpr source_location( char const* file, uint_least32_t line,
      char const* function, uint_least32_t column = 0 ) noexcept;
    constexpr source_location( std::source_location const& loc ) noexcept;

    constexpr char const* file_name() const noexcept;
    constexpr char const* function_name() const noexcept;
    constexpr uint_least32_t line() const noexcept;
    constexpr uint_least32_t column() const noexcept;

    std::string to_string() const;
};

template<class E, class T>
  std::basic_ostream<E, T> &
    operator<<( std::basic_ostream<E, T> & os, source_location const & loc );

} // namespace boost

#define BOOST_CURRENT_LOCATION /* see below */

source_location

constexpr source_location() noexcept;
Effects:

Constructs a source_location object for which file_name() and function_name() return "", and line() and column() return 0.

constexpr source_location( char const* file, uint_least32_t line,
  char const* function, uint_least32_t column = 0 ) noexcept;
Effects:

Constructs a source_location object for which file_name() returns file, function_name() returns function, line() returns the line argument and column() returns the column argument.

constexpr source_location( std::source_location const& loc ) noexcept;
Effects:

Constructs a source_location object for which file_name() returns loc.file_name(), function_name() returns loc.function_name(), line() returns loc.line() and column() returns loc.column().

to_string

std::string to_string() const;
Returns:

a string representation of *this.

operator<<

template<class E, class T>
  std::basic_ostream<E, T> &
    operator<<( std::basic_ostream<E, T> & os, source_location const & loc );
Effects:

os << loc.to_string().

Returns:

os.

BOOST_CURRENT_LOCATION

When BOOST_DISABLE_CURRENT_LOCATION is defined, the definition of BOOST_CURRENT_LOCATION is:

#define BOOST_CURRENT_LOCATION ::boost::source_location()

This allows producing executables that contain no identifying information, for security reasons.

Otherwise, BOOST_CURRENT_LOCATION is defined as the approximate equivalent of

#define BOOST_CURRENT_LOCATION \
    ::boost::source_location(::std::source_location::current())

Revision History

Changes in 1.79.0

  • source_location().file_name() and source_location().function_name() now return "" instead of "(unknown)".

  • Added a source_location constructor from std::source_location.

  • Changed BOOST_CURRENT_LOCATION to more closely match the behavior of std::source_location::current(), such as being usable at top level or as a default function argument.

Changes in 1.78.0

  • Added source_location::to_string.

Changes in 1.73.0

  • Added source_location.

This documentation is

  • Copyright 2002, 2007, 2014, 2017, 2019-2022 Peter Dimov

  • Copyright 2011 Beman Dawes

  • Copyright 2015 Ion GaztaƱaga

  • Distributed under the Boost Software License, Version 1.0.