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 toassert(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 macroNDEBUG
is defined. This allows users to selectively disableBOOST_ASSERT
without affecting the definition of the standardassert
. -
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 whetherNDEBUG
is defined.boost::assertion_failed
is declared in<boost/assert.hpp>
asnamespace boost { #if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) BOOST_NORETURN #endif 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)
whenNDEBUG
is defined. Otherwise the behavior is as ifBOOST_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 toassert((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 macroNDEBUG
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>
asnamespace boost { #if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) BOOST_NORETURN #endif 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)
whenNDEBUG
is defined. Otherwise the behavior is as ifBOOST_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 toBOOST_ASSERT(expr)
. -
Otherwise,
BOOST_VERIFY(expr)
expands to((void)(expr))
whenNDEBUG
is defined, toBOOST_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 toBOOST_ASSERT_MSG(expr,msg)
. -
Otherwise,
BOOST_VERIFY_MSG(expr,msg)
expands to((void)(expr))
whenNDEBUG
is defined, toBOOST_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 ifNDEBUG
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, thenBOOST_ASSERT_IS_VOID
is defined whenNDEBUG
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 whichfile_name()
andfunction_name()
return""
, andline()
andcolumn()
return0
.
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 whichfile_name()
returnsfile
,function_name()
returnsfunction
,line()
returns theline
argument andcolumn()
returns thecolumn
argument.
constexpr source_location( std::source_location const& loc ) noexcept;
- Effects:
-
Constructs a
source_location
object for whichfile_name()
returnsloc.file_name()
,function_name()
returnsloc.function_name()
,line()
returnsloc.line()
andcolumn()
returnsloc.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.88.0
-
When
BOOST_ASSERT_HANDLER_IS_NORETURN
is defined,boost::assertion_failed
andboost::assertion_failed_msg
are declared asBOOST_NORETURN
.
Changes in 1.79.0
-
source_location().file_name()
andsource_location().function_name()
now return""
instead of"(unknown)"
. -
Added a
source_location
constructor fromstd::source_location
. -
Changed
BOOST_CURRENT_LOCATION
to more closely match the behavior ofstd::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
.
Appendix A: Copyright and License
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.