boost.assert库提供了几个可配置的诊断宏,主要工具是BOOST_ASSERT,其行为和用途与<cassert>中的标准库assert类似,提供运行时断言,但是功能有所增强

为使用boost.assert,需要包含头文件<boost/assert.hpp>

基本用法

assert库定义了两个断言宏:

#define BOOST_ASSERT(expr)   assert(expr)
#define BOOST_ASSERT_MSG(expr, msg) assert((expr) && (msg));
  • 第一种形式的BOOST_ASSERT等同于assert宏,断言表达式为真。
  • 第二种形式则允许断言失败时输出描述性字符串,有助于拍错。
  • BOOST_VERIFY和BOOST_VERIFY_MSG都是BOOST_ASSERT的同义词,没有任何区别,仅为了兼容旧版本而存在

宏的参数expr表达式可以是任意(合法的)C++表示。从简单的关系比较到复杂的函数嵌套调用都可以。如果表达式值为true,那么断言成立,程序会继续往下执行,否则断言会引发一个异常,在终端上输出调试信息并终止程序的执行。比如:

BOOST_ASSERT(10 == 0x10);  //断言成立
BOOST_ASSERT(1 == 9);  // 断言失败,抛出异常

BOOST_ASSERT宏仅会在debug模式下生效,在release模式下不会进行编译,不会影响到运行效率。

看个例子:下面程序定义了一个func,使用BOOST_ASSERT确保不会出现除以0的错误:

double func(int x){BOOST_ASSERT_MSG(x != 0, "divided by zero");return 1.0/x;
}

在debug模式下运行:

int main()
{func(0);return 0;
}

禁用断言


断言宏,< boost/assert.hpp>

BOOST_ASSERT

头文件< boost/assert.hpp>用于定义BOOST_ASSERT,它类似于<cassert>中定义的标准assert宏,宏用于boost库和用户代码中。

  • 默认情况下,BOOST_ASSERT(expr)扩展为 assert(expr).
  • 如果#include <boost/assert.hpp> 时定义了宏BOOST_DISABLE_ASSERTS ,那么无论是否定义宏NDEBUG ,BOOST_ASSERT(expr)都会被扩展为((void)0),这允许用户有选择的禁用BOOST_ASSERT而不影响标准assert的定义
  • 如果#include <boost/assert.hpp> 时定义了宏BOOST_ENABLE_ASSERT_HANDLER ,BOOST_ASSERT(expr)将被扩展为:
(BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr,BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
  • 也就是说,先计算expr,如果为false,则自调用boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))。无论是否定义了NDEBUG,都是这样
  • boost::assertion_failed在< Boost /assert.hpp>中声明为
namespace boost
{void assertion_failed(char const * expr, char const * function,char const * file, long line);
}
  • 但它从未被定义。期望用户提供适当的定义。

  • 如果在#include <boost/assert.hpp> 时定义了宏BOOST_ENABLE_ASSERT_DEBUG_HANDLER,那么在定义NDEBUG时,BOOST_ASSERT(expr)扩展为((void)0)。否则,行为就好像定义了BOOST_ENABLE_ASSERT_HANDLER一样。

与< cassert>一样,< boost/assert.hpp>可以在一个翻译单元中包含多次。BOOST_ASSERT将按照上面的指定每次重新定义。

BOOST_ASSERT_MSG

宏BOOST_ASSERT_MSG类似于BOOST_ASSERT,但是它需要一个额外的参数:一个字符字面量,提供一个错误消息。

  • 默认情况下,BOOST_ASSERT_MSG(expr,msg)扩展为assert((expr)&&(msg))。
  • 如果在#include <boost/assert.hpp> 时定义了宏BOOST_DISABLE_ASSERTS ,那么无论是否定义宏NDEBUG , BOOST_ASSERT_MSG(expr,msg)扩展为((void)0)
  • 如果#include <boost/assert.hpp> 时定义了宏BOOST_ENABLE_ASSERT_HANDLER ,BOOST_ASSERT_MSG(expr,msg)将被扩展为:
(BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr,msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
  • 也就是说,先计算expr,如果为false,则自调用(BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))。无论是否定义了NDEBUG,都是这样
  • boost::assertion_failed_msg在< Boost /assert.hpp>中声明为
namespace boost
{void assertion_failed_msg(char const * expr, char const * msg,char const * function, char const * file, long line);
}
  • 但它从未被定义。期望用户提供适当的定义。

  • 如果在#include <boost/assert.hpp> 时定义了宏BOOST_ENABLE_ASSERT_DEBUG_HANDLER ,那么在定义NDEBUG时,BOOST_ASSERT_MSG(expr)扩展为((void)0)。否则,行为就好像定义了BOOST_ENABLE_ASSERT_HANDLER 一样。

与< cassert>一样,< boost/assert.hpp>可以在一个翻译单元中包含多次。BOOST_ASSERT_MSG将按照上面的指定每次重新定义。

BOOST_VERIFY

宏BOOST_VERIFY与BOOST_ASSERT具有相同的行为,只是传递给BOOST_VERIFY的表达式总是被求值。当断言的表达式具有理想的副作用时,这很有用;当变量仅在断言中使用时,它还可以帮助抑制关于未使用变量的警告。

  • 如果在#include <boost/assert.hpp> 时定义了宏BOOST_DISABLE_ASSERTS ,BOOST_VERIFY(expr)扩展为((void)0)
  • 如果在#include <boost/assert.hpp> 时定义了宏BOOST_ENABLE_ASSERT_HANDLER ,BOOST_VERIFY(expr)扩展为 BOOST_ASSERT(expr).
  • 否则,当NDEBUG被定义时,BOOST_VERIFY(expr)扩展为((void)(expr));当NDEBUG未被定义时,BOOST_ASSERT(expr)扩展为((void)(expr)。

BOOST_VERIFY_MSG

宏BOOST_VERIFY_MSG类似于BOOST_VERIFY,但是它需要一个额外的参数:一个字符字面量,提供一个错误消息。

  • 如果#include<boost/assert.hpp>时定义了宏BOOST_DISABLE_ASSERTS ,则BOOST_VERIFY_MSG(expr,msg)扩展为((void)(expr))
  • 如果#include<boost/assert.hpp>时定义了宏BOOST_ENABLE_ASSERT_HANDLER ,则BOOST_VERIFY_MSG(expr,msg)扩展为BOOST_ASSERT_MSG(expr,msg)
  • 否则,当NDEBUG被定义时,BOOST_VERIFY_MSG(expr,msg)扩展为((void)(expr));当未定义NDEBUG时,扩展为BOOST_ASSERT_MSG(expr,msg)。

BOOST_ASSERT_IS_VOID

宏BOOST_ASSERT_IS_VOID是在BOOST_ASSERT和BOOST_ASSERT_MSG展开为((void)0)时定义的。它的目的是避免编译和潜在地运行仅用于准备要在断言中使用的数据的代码。

  • 默认情况下,如果定义了NDEBUG,则定义BOOST_ASSERT_IS_VOID。
  • 如果定义了宏BOOST_DISABLE_ASSERTS , BOOST_ASSERT_IS_VOID也总是被定义。
  • 如果定义了宏BOOST_ENABLE_ASSERT_HANDLER,则永远不会定义BOOST_ASSERT_IS_VOID。
  • 如果定义了宏BOOST_ENABLE_ASSERT_DEBUG_HANDLER,那么在定义NDEBUG时也定义了BOOST_ASSERT_IS_VOID。
void MyContainer::erase(iterator i)
{// Some sanity checks, data must be ordered
#ifndef BOOST_ASSERT_IS_VOIDif(i != c.begin()) {iterator prev = i;--prev;BOOST_ASSERT(*prev < *i);}else if(i != c.end()) {iterator next = i;++next;BOOST_ASSERT(*i < *next);}#endifthis->erase_impl(i);
}

当前函数宏, < boost/current_function.hpp>

BOOST_CURRENT_FUNCTION

  • 头文件中<boost/current_function.hpp>定义了宏BOOST_CURRENT_FUNCTION,类似于C99预定义的标识符__func__
  • BOOST_CURRENT_FUNCTION展开为一个字符串字面值,包含外围函数的(完全限定的,如果可能的话)名称。如果没有封闭函数,则该行为是未指定的。
  • 有些编译器不提供获取当前封闭函数名称的方法。在这样的编译器上,或者在定义宏BOOST_DISABLE_CURRENT_FUNCTION时,BOOST_CURRENT_FUNCTION展开为"(unknown)"
  • BOOST_DISABLE_CURRENT_FUNCTION解决了一个用例,在这个用例中,程序员希望从最终的可执行文件中消除BOOST_CURRENT_FUNCTION产生的字符串字面量,这是出于安全原因。

源码文件位置支持, < boost/assert/source_location.hpp>

描述

  • 头文件 < boost/assert/source_location.hpp>定义了source_location,一个表示源位置的类,包含文件、行、函数和列信息。它类似于c++ 20中的std::source_location,但只需要c++ 03。

  • 宏BOOST_CURRENT_LOCATION创建一个source_location对象,其中包含关于当前源位置的信息。

类摘要

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 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;
};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 \::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION)

source_location

constexpr source_location() noexcept;
  • 效果:构造一个source_location对象,其中file_name()和function_name()返回"(unknown)",line()和column()返回0。
constexpr source_location(char const* file, uint_least32_t line,char const* function, uint_least32_t column = 0) noexcept;
  • 效果:构造一个source_location对象,其中file_name()返回file, function_name()返回function, line()返回line参数,column()返回column参数。
template<class E, class T>std::basic_ostream<E, T> &operator<<( std::basic_ostream<E, T> & os, source_location const & loc );
  • 效果:将loc的字符串表示形式输出到os。
  • 返回值:os

BOOST_CURRENT_LOCATION

  • 当BOOST_DISABLE_CURRENT_LOCATION没有定义时,BOOST_CURRENT_LOCATION的定义是:
#define BOOST_CURRENT_LOCATION \::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION)
  • 否则,BOOST_CURRENT_LOCATION的定义是:
#define BOOST_CURRENT_LOCATION ::boost::source_location()

这允许出于安全原因生成不包含识别信息的可执行文件。

boost:assert相关推荐

  1. Boost:循环缓冲区总和的测试程序

    Boost:循环缓冲区总和的测试程序 实现功能 C++实现代码 实现功能 循环缓冲区总和的测试程序 C++实现代码 #include <boost/circular_buffer.hpp> ...

  2. Boost:循环缓冲区迭代的测试程序

    Boost:循环缓冲区迭代的测试程序 实现功能 C++实现代码 实现功能 循环缓冲区迭代的测试程序 C++实现代码 #undef BOOST_CB_ENABLE_DEBUG #define BOOST ...

  3. Boost:BOOST_ASSERT用法的测试程序

    Boost:BOOST_ASSERT的用法测试程序 实现功能 C++实现代码 实现功能 BOOST_ASSERT的测试程序 C++实现代码 #include <boost/assert.hpp& ...

  4. Boost:boost::source_location的用法测试程序

    Boost:boost::source_location的用法测试程序 实现功能 C++实现代码 实现功能 boost::source_location的用法测试程序 C++实现代码 #include ...

  5. Boost:BOOST_VERIFY的用法测试程序

    Boost:BOOST_VERIFY的用法测试程序 实现功能 C++实现代码 实现功能 BOOST_VERIFY的用法测试程序 C++实现代码 #include <boost/core/ligh ...

  6. Boost:bimap双图的突变关系的测试程序

    Boost:bimap双图的突变关系的测试程序 实现功能 C++实现代码 实现功能 bimap双图的突变关系的测试程序 C++实现代码 #include <boost/config.hpp> ...

  7. boost:lexical_cast

    概述 顾名思义,lexical_cast库进行"字面值"的转换,类似C中的atoi()函数,可以进行字符串与整数/浮点数之间的字面转换 标准C和c++库提供了许多用于执行此类转换的 ...

  8. boost:filesystem

    目录.文件处理是脚本语言如shell.python所擅长的领域,C++语言缺乏对操作系统文件的查询和操作能力,因此C++程序员经常需要再掌握另外一门脚本语言以方便自己的工作,这增加了学习成本 file ...

  9. boost:从0到1开发boost(linux、clion)

    boost 1.安装包下载 下载地址 选一个就好 并将安装包放到centos的适当目录下 2.设置编译器和所选库 解压 $ tar -xvf boost_1_74_0_b1.tar.bz2 运行解压后 ...

最新文章

  1. 【数字信号处理】序列傅里叶变换 ( 序列傅里叶变换定义详细分析 | 证明单位复指数序列正交完备性 | 序列存在傅里叶变换的性质 | 序列绝对可和 → 序列傅里叶变换一定存在 )
  2. 一些有用的Linux命令
  3. 亿级大表分库分表实战总结(万字干货,实战复盘)
  4. Galgame研发日志:那么,怎么才能回本呢?
  5. 待遇 新时达机器人_践行中国制造2025:工业机器人企业突围之路
  6. 数据结构-链表1-顺序存储
  7. r语言worldclim数据_R语言空间数据分析(五):栅格数据处理
  8. 福师计算机应用基础期末,福师2015计算机应用基础》期末试卷A123
  9. Algs4-1.2.8引用型变量赋值-数组复制
  10. EF架构~看看下面这代码,你还敢用它的延时加载吗?
  11. 车牌识别及提取系统MATLAB,车牌识别系统设计及MATLAB仿真
  12. 蓝方防守、HW总结报告模板
  13. Word一行排列多个图片并插入题注
  14. 设置来电铃声android,设置默认来电铃声 android
  15. oracle 增量导出 导入,Oracle增量导入导出
  16. 让你彻底明白什么是BFC及作用?
  17. write-back与Write-through
  18. STM32CubeMX和keil实现led灯的点亮
  19. JDK8 日期时间相关 java.time.*
  20. 基于LM的双目图像校准算法源码第一部分

热门文章

  1. 读《Weighted Graph Based Description for Finger-Vein Recognition》
  2. 初雨CPPHelper使用说明
  3. php自动收录导航程序,2020最新自动收录自带查反链导航源码 自动收录导航批量检查反链系统简介程序...
  4. bzoj 1934: [Shoi2007]Vote 善意的投票(最小割)
  5. 亚商投资顾问 早餐FM/1130物流需求延续逐步恢复态势
  6. golang学习笔记(基础篇)
  7. 通过4G模块定位设备
  8. Java处理小数点精度
  9. PyQt5 实现矩阵计算器
  10. 机房收费系统(VB.NET)——超详细的报表制作过程