assert
C/C++提供的assert宏只支持有限的正确性验证,所以boost在这方面进行了改进: boost.assert 库增强了原始的运行时的 assert 宏, static_assert 库提供了静态断言(编译期诊断),而lightweight_test 和 test 库则构建了完整的单元测试框架。
assert
boost.assert提供了BOOST_ASSERT和BOOST_ASSERT_MSG两种形式,BOOST_ASSERT等同于C/C++提供的assert宏,断言表达式为真;BOOST_ASSERT_MSG在断言失败时可输出描述字符串。如果断言的表达式为真,那么断言成立,程序继续执行,否则断言会引发一个异常。
正常情况下,BOOST_ASSERT和BOOST_ASSERT_MSG以及C/C++提供的assert宏仅在debug模式下生效,在release下不会进行编译,不会影响到运行效率。
void TestAssert()
{
int a = 10;
int* p = &a;
BOOST_ASSERT(*p == 10); //Assertion failed:*p==11, file D:\FCJProject\VSProgram\boostStudy\boostStudy\StudyTest.cpp, line 8
assert(*p == 11);//Assertion failed: *p==11, file D:\FCJProject\VSProgram\boostStudy\boostStudy\StudyTest.cpp, line 9
BOOST_ASSERT_MSG(*p == 11, "failed"); //Assertion failed: (*p==11)&&("failed"),file D:\FCJProject\VSProgram\boostStudy\boostStudy\StudyTest.cpp, line 11
}
禁用boost.assert
在头文件<boost/assert.hpp>前定义宏#define BOOST_DISABLE_ASSERTS后,即便在debug模式下,boost.assert将自动生效。但C/C++标准下的assert宏不会受影响。
release版本下使用boost.assert
在头文件 <boost/assert.hpp>前定义宏#define BOOST_ENABLE_ASSERT_HANDLER后,boost.assert的行为将发生改变:它将不再等同于 assert 宏,断言的表达式无论是在debug模式下还是在 release 模式下,都将被求值。如果断言失败,会发生一个断言失败的函数调用 boost:: assertion_failed 或assertion_failed_msg ——这相当于提供了一个错误处理 handler(注意:这两个函数需要自己实现) 。handler一般指的是(处理特定事件或消息的函数或方法。它是一种回调函数,用于响应用户输入、系统事件或其他触发器。Handler 的主要作用是接收、处理和响应这些事件或消息)。
namespace boost {
void assertion_failed(char const* expr, char const* function, char const* file, long line);
void assertion_failed_msg(char const* expr, char const* msg, char const* function, char const* file, long line);
}
void boost::assertion_failed(char const* expr, char const* function, char const* file, long line)
{
}
void boost::assertion_failed_msg(char const* expr, char const* msg, char const* function, char const* file, long line)
{
std::cout << "expr:" << expr
<< " ,msg:" << msg
<< " ,function:" << function
<< " ,file:" << file
<< " ,line:" << line << std::endl;
}
static_assert
C/C++标准下的assert宏和boost.assert宏是用于运行时的断言,它们是程序员的好帮手,应该在程序中被广泛应用。但有些时候,运行时的断言太晚了,程序已经发生了无可挽回的错误。
static_assert 库把断言的诊断时刻由运行期提前到编译期,让编译器检查可能发生的错误,这样
能够更好地增加程序的正确性,它模拟实现了C ++ 标准里的 static_assert 关键字。
boost.static_assert提供了BOOST_STATIC_ASSERT和BOOST_STATIC_ASSERT_MSG两种形式,无论debug模式还是release模式都生效。如果编译器不支持C++标准的新关键字static_assert,那么BOOST_STATIC_ASSERT_MSG类似于BOOST_STATIC_ASSERT,字符串消息功能会失效。
lightweight_test
测试断言
lightweight_test 是一个轻量级的单元测试框架,只提供最基本的单元测试功能,不支持测试用例、测试套件的概念,但因为它简单小巧,所以它适用于要求不高或快速的测试工作(不适用于大多数实际的软件开发项目)。
lightweight_test 不需要编译,也不需要特定的入口函数,测试断言可以用在程序里的任何地方,就像使用 assert 一样,如果断言失败,就会增加内部的错误计数,lightweight_test 提供函数 boost.report_errors ( ) 来输出测试结果,在测试结束时,我们必须调用 report_errors( ),否则会发生 BOOST_ASSERT 断言错误。
#include <boost/core/lightweight_test.hpp>
void TestLightWeightTest()
{
std::shared_ptr<int> p = std::make_shared<int>(10);
BOOST_TEST(*p == 10);
BOOST_TEST(p.unique());
BOOST_TEST_EQ(p.use_count(), 1);
BOOST_TEST_NE(*p, 10);//*p等于10,断言失败
std::cout << boost::report_errors() << std::endl;
//D:\FCJProject\VSProgram\boostStudy\boostStudy\StudyTest.cpp(40) : test '*p != 10' ('10' != '10') failed in function 'void __thiscall StudyTest::TestLightWeightTest(void)'
//1 errors detected.
//1
}
测试元编程
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
#define BOOST_TEST_TRAIT_FALSE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, false, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
这两个宏的效果与 BOOST_STATIC_ASSERT 类似,但它们判断的是 type::value ,而不是type本身,所以宏的参数 type 应该是能够返回bool值的元函数。还需要特别注意:由于内部实现的原因, type 必须要使用圆括号包围(宏展开为一个模板函数的参数)。
#include <boost/core/lightweight_test_trait.hpp>
void TestLightWeightTest()
{
BOOST_TEST_TRAIT_TRUE((std::is_integral<int>));
BOOST_TEST_TRAIT_TRUE((std::is_function<int>));//int不是函数,断言失败
std::cout << boost::report_errors() << std::endl;
//D:\FCJProject\VSProgram\boostStudy\boostStudy\StudyTest.cpp(43) : predicate '(std::is_function<int>)'[struct std::is_function<int>] test failed in function 'void __thiscall StudyTest::TestLightWeightTest(void)' (should have been true)
//1 errors detected.
//1
}
实际上还有TEST库
//todo