|
Boost : |
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2022-02-14 03:09:58
On 2/14/22 00:43, Peter Dimov via Boost wrote:
> This is a quick summary of some 1.78 and 1.79 changes in Assert,
> ThrowException, and System related to error reporting.
>
> In Boost 1.73, Assert acquired a new component,
> boost::source_location. This is a class encapsulating a source
> location (a collection of source file name, line number, column,
> and function name) that is modeled after C++20's
> std::source_location, except of course it doesn't require C++20.
>
> In 1.79, the macro that creates the current source location,
> BOOST_CURRENT_LOCATION, is now usable in a function default
> argument, similarly to std::source_location::current(). This
> enables functions to be declared like this:
>
> T& my_vector::at( size_t i, boost::source_location const&
> loc = BOOST_CURRENT_LOCATION )
> {
> if( i >= size() )
> {
> boost::throw_exception( std::out_of_range( "at" ),
> loc );
> }
>
> return data_[ i ];
> }
>
> Since functions such as `at` are called from many places in the
> program, it's more useful for the source location in the thrown
> exception to point at the call site, rather than inside of `at`
> (which doesn't provide much information.)
>
> See for example https://godbolt.org/z/6o9e187a1. Note that the
> location returned by diagnostic_information(x) points to line 35,
> which is the call to `v.at(5);` inside `main`.
>
> Recommendation one: add source_location default arguments to your
> throwing functions so that the information logged at the catch site
> points to the call that threw.
>
> In case you find boost::throw_exception too heavyweight, as it
> adds a boost::exception base class and support for boost::exception_ptr,
> and this would prevent you from applying the technique above, there
> is now an alternative function, boost::throw_with_location, in
> <boost/throw_exception.hpp>. It doesn't integrate with Boost.Exception
> or boost::exception_ptr, but does add a source location to the exception
> that can later be retrieved with boost::get_throw_location(x).
>
> The above example using boost::throw_with_location can be seen at
> https://godbolt.org/z/Pcj1xad3v.
>
> In 1.78, boost::system::error_code had also acquired support for source
> locations, although it's not as automatic as the above technique where the
> default argument automatically adds a location without the user needing to
> do anything.
>
> Since there's no space in error_code for the entire boost::source_location
> struct, it can only store a pointer to it. This requires the following
> incantation
>
> BOOST_STATIC_CONSTEXPR boost::source_location loc = BOOST_CURRENT_LOCATION;
> ec.assign( ENOENT, boost::system::generic_category(), &loc );
>
> which can be wrapped in a macro. See the documentation of Boost.System:
>
> https://www.boost.org/doc/libs/1_78_0/libs/system/doc/html/system.html#usage_attaching_a_source_location_to_error_codes
>
> Unlike the case with exceptions, when working with error codes, the
> situation is reversed and we want to store the source location immediately
> after discovering the error, rather than the one of the user call that
> failed. That's both because this location gives the most information as
> to the source of the error (ENOENT on its own doesn't say much), and
> because error codes are generally checked close to the user call, so the
> call location isn't as useful.
>
> Recommendation two: add source locations to your error_codes if using
> Boost.System.
>
> Finally, when providing dual APIs, that is, APIs that can signal an error
> using both error_code or by throwing an exception, you can combine the
> above two approaches and store both the "deep" source location in the
> error_code and the "shallow" (user call) location in the system_error
> exception.
>
> I hope you find those useful.
>
> Further reading:
>
> https://www.boost.org/doc/libs/develop/libs/assert/doc/html/assert.html#source_location_support
> https://www.boost.org/doc/libs/develop/libs/throw_exception/doc/html/throw_exception.html
> https://www.boost.org/doc/libs/develop/libs/system/doc/html/system.html
Thank you, Peter.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk