Brian Silverman | ea861c1 | 2018-08-04 17:43:02 -0700 | [diff] [blame^] | 1 | //// |
| 2 | Copyright 2002, 2007, 2014, 2017 Peter Dimov |
| 3 | Copyright 2011 Beman Dawes |
| 4 | Copyright 2015 Ion Gaztañaga |
| 5 | |
| 6 | Distributed under the Boost Software License, Version 1.0. |
| 7 | |
| 8 | See accompanying file LICENSE_1_0.txt or copy at |
| 9 | http://www.boost.org/LICENSE_1_0.txt |
| 10 | //// |
| 11 | |
| 12 | # Assertion Macros, <boost/assert.hpp> |
| 13 | :toc: |
| 14 | :toc-title: |
| 15 | :idprefix: |
| 16 | |
| 17 | ## BOOST_ASSERT |
| 18 | |
| 19 | The header `<boost/assert.hpp>` defines the macro `BOOST_ASSERT`, |
| 20 | which is similar to the standard `assert` macro defined in `<cassert>`. |
| 21 | The macro is intended to be used in both Boost libraries and user |
| 22 | code. |
| 23 | |
| 24 | * By default, `BOOST_ASSERT(expr)` expands to `assert(expr)`. |
| 25 | |
| 26 | * If the macro `BOOST_DISABLE_ASSERTS` is defined when `<boost/assert.hpp>` |
| 27 | is included, `BOOST_ASSERT(expr)` expands to `((void)0)`, regardless of whether |
| 28 | the macro `NDEBUG` is defined. This allows users to selectively disable `BOOST_ASSERT` without |
| 29 | affecting the definition of the standard `assert`. |
| 30 | |
| 31 | * If the macro `BOOST_ENABLE_ASSERT_HANDLER` is defined when `<boost/assert.hpp>` |
| 32 | is included, `BOOST_ASSERT(expr)` expands to |
| 33 | + |
| 34 | ``` |
| 35 | (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, |
| 36 | BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) |
| 37 | ``` |
| 38 | + |
| 39 | That is, it evaluates `expr` and if it's false, calls |
| 40 | `::boost::assertion_failed(#expr, <<current_function.adoc#boost_current_function,BOOST_CURRENT_FUNCTION>>, \\__FILE__, \\__LINE__)`. |
| 41 | This is true regardless of whether `NDEBUG` is defined. |
| 42 | + |
| 43 | `boost::assertion_failed` is declared in `<boost/assert.hpp>` as |
| 44 | + |
| 45 | ``` |
| 46 | namespace boost |
| 47 | { |
| 48 | void assertion_failed(char const * expr, char const * function, |
| 49 | char const * file, long line); |
| 50 | } |
| 51 | ``` |
| 52 | + |
| 53 | but it is never defined. The user is expected to supply an appropriate definition. |
| 54 | |
| 55 | * If the macro `BOOST_ENABLE_ASSERT_DEBUG_HANDLER` is defined when `<boost/assert.hpp>` |
| 56 | is included, `BOOST_ASSERT(expr)` expands to `((void)0)` when `NDEBUG` is |
| 57 | defined. Otherwise the behavior is as if `BOOST_ENABLE_ASSERT_HANDLER` has been defined. |
| 58 | |
| 59 | As is the case with `<cassert>`, `<boost/assert.hpp>` |
| 60 | can be included multiple times in a single translation unit. `BOOST_ASSERT` |
| 61 | will be redefined each time as specified above. |
| 62 | |
| 63 | ## BOOST_ASSERT_MSG |
| 64 | |
| 65 | The macro `BOOST_ASSERT_MSG` is similar to `BOOST_ASSERT`, but it takes an additional argument, |
| 66 | a character literal, supplying an error message. |
| 67 | |
| 68 | * By default, `BOOST_ASSERT_MSG(expr,msg)` expands to `assert\((expr)&&(msg))`. |
| 69 | |
| 70 | * If the macro `BOOST_DISABLE_ASSERTS` is defined when `<boost/assert.hpp>` |
| 71 | is included, `BOOST_ASSERT_MSG(expr,msg)` expands to `((void)0)`, regardless of whether |
| 72 | the macro `NDEBUG` is defined. |
| 73 | |
| 74 | * If the macro `BOOST_ENABLE_ASSERT_HANDLER` is defined when `<boost/assert.hpp>` |
| 75 | is included, `BOOST_ASSERT_MSG(expr,msg)` expands to |
| 76 | + |
| 77 | ``` |
| 78 | (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, |
| 79 | msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) |
| 80 | ``` |
| 81 | + |
| 82 | This is true regardless of whether `NDEBUG` is defined. |
| 83 | + |
| 84 | `boost::assertion_failed_msg` is declared in `<boost/assert.hpp>` as |
| 85 | + |
| 86 | ``` |
| 87 | namespace boost |
| 88 | { |
| 89 | void assertion_failed_msg(char const * expr, char const * msg, |
| 90 | char const * function, char const * file, long line); |
| 91 | } |
| 92 | ``` |
| 93 | + |
| 94 | but it is never defined. The user is expected to supply an appropriate definition. |
| 95 | |
| 96 | * If the macro `BOOST_ENABLE_ASSERT_DEBUG_HANDLER` is defined when `<boost/assert.hpp>` |
| 97 | is included, `BOOST_ASSERT_MSG(expr)` expands to `((void)0)` when `NDEBUG` is |
| 98 | defined. Otherwise the behavior is as if `BOOST_ENABLE_ASSERT_HANDLER` has been defined. |
| 99 | |
| 100 | As is the case with `<cassert>`, `<boost/assert.hpp>` |
| 101 | can be included multiple times in a single translation unit. `BOOST_ASSERT_MSG` |
| 102 | will be redefined each time as specified above. |
| 103 | |
| 104 | ## BOOST_VERIFY |
| 105 | |
| 106 | The macro `BOOST_VERIFY` has the same behavior as `BOOST_ASSERT`, except that |
| 107 | the expression that is passed to `BOOST_VERIFY` is always |
| 108 | evaluated. This is useful when the asserted expression has desirable side |
| 109 | effects; it can also help suppress warnings about unused variables when the |
| 110 | only use of the variable is inside an assertion. |
| 111 | |
| 112 | * If the macro `BOOST_DISABLE_ASSERTS` is defined when `<boost/assert.hpp>` |
| 113 | is included, `BOOST_VERIFY(expr)` expands to `\((void)(expr))`. |
| 114 | |
| 115 | * If the macro `BOOST_ENABLE_ASSERT_HANDLER` is defined when `<boost/assert.hpp>` |
| 116 | is included, `BOOST_VERIFY(expr)` expands to `BOOST_ASSERT(expr)`. |
| 117 | |
| 118 | * Otherwise, `BOOST_VERIFY(expr)` expands to `\((void)(expr))` when `NDEBUG` is |
| 119 | defined, to `BOOST_ASSERT(expr)` when it's not. |
| 120 | |
| 121 | ## BOOST_VERIFY_MSG |
| 122 | |
| 123 | The macro `BOOST_VERIFY_MSG` is similar to `BOOST_VERIFY`, with an additional parameter, an error message. |
| 124 | |
| 125 | * If the macro `BOOST_DISABLE_ASSERTS` is defined when `<boost/assert.hpp>` |
| 126 | is included, `BOOST_VERIFY_MSG(expr,msg)` expands to `\((void)(expr))`. |
| 127 | |
| 128 | * If the macro `BOOST_ENABLE_ASSERT_HANDLER` is defined when `<boost/assert.hpp>` |
| 129 | is included, `BOOST_VERIFY_MSG(expr,msg)` expands to `BOOST_ASSERT_MSG(expr,msg)`. |
| 130 | |
| 131 | * Otherwise, `BOOST_VERIFY_MSG(expr,msg)` expands to `\((void)(expr))` when `NDEBUG` is |
| 132 | defined, to `BOOST_ASSERT_MSG(expr,msg)` when it's not. |
| 133 | |
| 134 | ## BOOST_ASSERT_IS_VOID |
| 135 | |
| 136 | The macro `BOOST_ASSERT_IS_VOID` is defined when `BOOST_ASSERT` and `BOOST_ASSERT_MSG` are expanded to `((void)0)`. |
| 137 | Its purpose is to avoid compiling and potentially running code that is only intended to prepare data to be used in the assertion. |
| 138 | |
| 139 | ``` |
| 140 | void MyContainer::erase(iterator i) |
| 141 | { |
| 142 | // Some sanity checks, data must be ordered |
| 143 | #ifndef BOOST_ASSERT_IS_VOID |
| 144 | |
| 145 | if(i != c.begin()) { |
| 146 | iterator prev = i; |
| 147 | --prev; |
| 148 | BOOST_ASSERT(*prev < *i); |
| 149 | } |
| 150 | else if(i != c.end()) { |
| 151 | iterator next = i; |
| 152 | ++next; |
| 153 | BOOST_ASSERT(*i < *next); |
| 154 | } |
| 155 | |
| 156 | #endif |
| 157 | |
| 158 | this->erase_impl(i); |
| 159 | } |
| 160 | ``` |
| 161 | |
| 162 | * By default, `BOOST_ASSERT_IS_VOID` is defined if `NDEBUG` is defined. |
| 163 | * If the macro `BOOST_DISABLE_ASSERTS` is defined, `BOOST_ASSERT_IS_VOID` is always defined. |
| 164 | * If the macro `BOOST_ENABLE_ASSERT_HANDLER` is defined, `BOOST_ASSERT_IS_VOID` is never defined. |
| 165 | * If the macro `BOOST_ENABLE_ASSERT_DEBUG_HANDLER` is defined, then `BOOST_ASSERT_IS_VOID` is defined when `NDEBUG` is defined. |