时间:2014.01.29
地点:平口家里
———————————————————————————————————
一、简述
所谓运动态断言就是在程序运行时检查断言,静态断言则是在编译时检查断言。为什么需要断言,其实这是一种有效的程序调试方式,方便我们尽快的发现错误,如果语句违背我们的意愿,我们可以马上发现错误进行修改,在Release版中,断言语句会失效,从而不会影响程序性能而又安全。
———————————————————————————————————
二、静态断言
静态断言是C++11语法,在无需头文件下,我们可以很方便的使用静态断言,使用范围包括全局范围,命名空间、函数体、类的声明。例如,我们在编写跨平台代码时,有时代码可能在客户站点上崩溃,因为整数的大小并不是你所期待的4byte。使用断言我们可以及早的准备、准确地找到错误。
static_assert(sizeof(int) == 4, "Integer sizes expected to be 6"); int main() { return 0; }这样,在sizeof(int)不为4的情况下,编译就不能通过,并提示错误所在行。
有如在类声明中,我们有如下主模板和特化模板,对于特化模板,若传入类型参数不合断言,则编译错误。
template<typename T1,typename T2> class MyClass { T1 a; T2 b; }; template<typename T1> class MyClass<T1, bool> { static_assert(sizeof(T1) == 4, "MyClass<T1,bool>is not allowed"); }; int main() { //MyClass<char, bool> f1; //此处引用特化模板,但断言不通过,因此编译错误 MyClass<float, int> f2; return 0; }
静态断言在编译时检查程序,不影响程序运行,但缺陷是断言本身必须是常量表到式。因为我们还介绍动态断言,弥补这个不足。
———————————————————————————————————
三、动态断言
动态断言早已有之,需要引用头文件#include<cassert>,函数assert在调试阶段今早发现“不可能”事件,若真发生了,表示代码逻辑有误,程序abort,并产生诊断信息,方便修改程序。
例如:
#include<cassert> using namespace std; int main() { int i = 227; assert(i != 227); //我们断言i是不等于227的,但事实上它等于了,违背了我们的断言,所以程序运行到此时会abort return 0; }