...one of the most highly
regarded and expertly designed C++ library projects in the
world.
—
Herb Sutter
and
Andrei
Alexandrescu
,
C++
Coding Standards
Boost.ThrowException
Peter Dimov, Emil Dotchevski
Table of Contents
Description
Examples
Using BOOST_THROW_EXCEPTION
Using boost::throw_exception with a source location
Using boost::throw_with_location
Using boost::throw_with_location with an explicit source location
Revision History
Changes in 1.79.0
Changes in 1.73.0
Reference
<boost/throw_exception.hpp> Synopsis
throw_exception
throw_with_location
get_throw_location
The header
<boost/throw_exception.hpp>
provides a common Boost infrastructure
for throwing exceptions, in the form of a function
boost::throw_exception
and a macro
BOOST_THROW_EXCEPTION
.
boost::throw_exception(x);
is a replacement for
throw x;
that both
degrades gracefully when exception handling support is not available, and
integrates the thrown exception into facilities provided by
Boost.Exception
, such as automatically
providing a base class of type
boost::exception
and support for
boost::exception_ptr
.
When exception handling is not available, the function is only declared, but
not defined. This allows users to provide their own definition.
An overload for
boost::throw_exception
that takes a
boost::source_location
is provided. It records the supplied source location into the
boost::exception
base class, from where it can later be retrieved when the exception is caught.
boost::diagnostic_information
automatically displays the stored source location.
The macro
BOOST_THROW_EXCEPTION(x)
expands to
::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
, passing the current source
location.
When integration with Boost.Exception and
boost::exception_ptr
is not needed,
the function
boost::throw_with_location
can be used instead. It also throws
a user-provided exception, associating it with a supplied or inferred source
location, but does not supply the
boost::exception
base class and does not
enable
boost::exception_ptr
support.
The source location of the exception thrown by
boost::throw_with_location
can be retrieved, after
catch(std::exception const & x)
, by using
boost::get_throw_location(x)
.
boost::get_throw_location
also works for exceptions thrown by the two argument
overload of
boost::throw_exception
, or by
BOOST_THROW_EXCEPTION
; in this case
it returns the source location stored in the
boost::exception
base class.
#include <boost/throw_exception.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <stdexcept>
#include <iostream>
void f()
BOOST_THROW_EXCEPTION( std::runtime_error( "Unspecified runtime error" ) );
int main()
f();
catch( std::exception const & x )
std::cerr << boost::diagnostic_information( x ) << std::endl;
example.cpp(8): Throw in function void f()
Dynamic exception type: boost::wrapexcept<std::runtime_error>
std::exception::what: Unspecified runtime error
Using boost::throw_exception with a source location
Demonstrates moving the call to boost::throw_exception
to a common
helper function that can be marked BOOST_NOINLINE
to avoid
unnecessary code duplication. The source location is passed
explicitly to the helper function so that it can still record the
logical throw point, instead of always pointing into the helper.
#include <boost/throw_exception.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/core/verbose_terminate_handler.hpp>
#include <stdexcept>
#include <cstddef>
#include <iostream>
BOOST_NORETURN BOOST_NOINLINE
void throw_index_error( std::size_t i, std::size_t n,
boost::source_location const & loc )
std::string msg = "Index out of range: "
+ boost::lexical_cast<std::string>( i ) + " >= "
+ boost::lexical_cast<std::string>( n );
boost::throw_exception( std::out_of_range( msg ), loc );
void f1( std::size_t i, std::size_t n )
if( i >= n )
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
void f2( std::size_t i, std::size_t n )
if( i >= n )
throw_index_error( i, n, BOOST_CURRENT_LOCATION );
int main()
std::set_terminate( boost::core::verbose_terminate_handler );
f1( 0, 3 );
f2( 4, 3 );
std::terminate called after throwing an exception:
type: boost::wrapexcept<std::out_of_range>
what(): Index out of range: 4 >= 3
location: <source>:31:34 in function 'f2'
Using boost::throw_with_location
This example demonstrates a trivial use of boost::throw_with_location
. Since
a source location is not supplied, the location of the call to
boost::throw_with_location
is implicitly captured.
#include <boost/throw_exception.hpp>
#include <boost/core/verbose_terminate_handler.hpp>
#include <stdexcept>
int f1( int x )
if( x < 0 )
boost::throw_with_location(
std::invalid_argument( "f1: x cannot be negative" ) );
return x;
int main()
std::set_terminate( boost::core::verbose_terminate_handler );
return f1( -4 );
std::terminate called after throwing an exception:
type: boost::detail::with_throw_location<std::invalid_argument>
what(): f1: x cannot be negative
location: <source>:9:9 in function 'f1'
Using boost::throw_with_location with an explicit source location
In this example, the call to boost::throw_with_location
is moved into
a common helper function. Note how the "API" functions f1
and f2
take a source location argument that defaults to BOOST_CURRENT_LOCATION
.
This allows the source location attached to the exception to point at
the location of the call to f2
, rather than inside of f2
.
Since functions such as f2
are typically called from more than one place
in the program, this is usually what we want, because it enables us to
identify the throwing call, rather than merely to know that it was f2
that threw.
#include <boost/throw_exception.hpp>
#include <boost/core/verbose_terminate_handler.hpp>
#include <stdexcept>
BOOST_NORETURN BOOST_NOINLINE
void throw_invalid_argument( char const * msg,
boost::source_location const & loc )
boost::throw_with_location( std::invalid_argument( msg ), loc );
int f1( int x,
boost::source_location const & loc = BOOST_CURRENT_LOCATION )
if( x < 0 )
throw_invalid_argument( "f1: x cannot be negative", loc );
return x;
int f2( int x,
boost::source_location const & loc = BOOST_CURRENT_LOCATION )
if( x < 0 )
throw_invalid_argument( "f2: x cannot be negative", loc );
return x;
int main()
std::set_terminate( boost::core::verbose_terminate_handler );
return f1( 3 ) + f2( -11 );
std::terminate called after throwing an exception:
type: boost::detail::with_throw_location<std::invalid_argument>
what(): f2: x cannot be negative
location: <source>:38:22 in function 'main'
#if defined( BOOST_NO_EXCEPTIONS )
BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
BOOST_NORETURN void throw_exception( std::exception const & e,
boost::source_location const & loc ); // user defined
#else
template<class E> BOOST_NORETURN void throw_exception( E const & e );
template<class E> BOOST_NORETURN void throw_exception( E const & e,
boost::source_location const & loc );
#endif
} // namespace boost
#define BOOST_THROW_EXCEPTION(x) \
::boost::throw_exception(x, BOOST_CURRENT_LOCATION)
namespace boost
template<class E> BOOST_NORETURN void throw_with_location( E && e,
boost::source_location const & loc = BOOST_CURRENT_LOCATION );
template<class E> boost::source_location get_throw_location( E const & e );
} // namespace boost
#if defined( BOOST_NO_EXCEPTIONS )
BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined
#else
template<class E> BOOST_NORETURN void throw_exception( E const & e );
#endif
When exceptions aren’t available, the function is declared, but
not defined. The user is expected to supply an appropriate definition.
Otherwise, if
BOOST_EXCEPTION_DISABLE
is defined, the function
throws
e
.
Otherwise, the function throws an object of a type derived from
E
,
derived from
boost::exception
, if
E
doesn’t already derive from
it, and containing the necessary support for
boost::exception_ptr
.
#if defined( BOOST_NO_EXCEPTIONS )
BOOST_NORETURN void throw_exception( std::exception const & e,
boost::source_location const & loc ); // user defined
#else
template<class E> BOOST_NORETURN void throw_exception( E const & e,
boost::source_location const & loc );
#endif
When exceptions aren’t available, the function is declared, but
not defined. The user is expected to supply an appropriate definition.
Otherwise, if
BOOST_EXCEPTION_DISABLE
is defined, the function
throws
e
.
Otherwise, the function throws an object of a type derived from
E
,
derived from
boost::exception
, if
E
doesn’t already derive from
it, and containing the necessary support for
boost::exception_ptr
. The
boost::exception
base class is initialized to contain the source
location
loc
.
Otherwise, the function throws an object of a type derived from
E
,
such that, if this object
x
is caught as
std::exception
or
E
,
boost::get_throw_location( x )
would return
loc
.
If
e
is a subobject of the object thrown by
boost::throw_with_location( x, loc )
, returns
loc
.
If
dynamic_cast<boost::exception const*>( e )
returns a nonzero value, returns the source location stored in that
boost::exception
subobject, if any.
Otherwise, returns a default constructed source location.