从LLVM源码学C++(四)

关键知识点:断言linux

1 const Option OptTable::getOption(OptSpecifier Opt) const {
2   unsigned id = Opt.getID();
3   if (id == 0)
4     return Option(0, 0);
5   assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
6   return Option(&getInfo(id), this);
7 }

断言:(转)http://blog.csdn.net/szlanny/article/details/4267862程序员

断言的应该是一种编程的常见技巧。我所应用的断言有两种,一种是动态断言,即你们所熟知的C标准库的assert()宏,一种是C++中的静态断言,即在编译期间检查。express

 

1)动态断言:assert宏的原型定义在<assert.h>中,其做用是若是它的条件返回错误,则终止程序执行,原型定义:编程

[c-sharp]  view plain copy
 
  1. #include <assert.h>  
  2. void assert( int expression );  

 

assert的做用是先计算表达式 expression ,若是其值为假(即为0),那么它先向stderr打印一条出错信息,而后经过调用 abort 来终止程序运行。
你们要注意是,其中的表达式为假时,会终止程序运行,包括我在内常常会写错代码,断言一个指针是否为空,每每写成了
assert(!p);其实应该写成assert(p);
assert是运行期的判断,而且会强制终止程序,通常要求只能用于debug版本中,是为了尽量快的发现问题。尤为在我所从事的电信软件产品中,assert是要从release版本中去掉。因此通常开发会从新定义assert宏。this


2)静态断言,在新的C++标准中C++0x中,加了对静态断言的支持,引入了新的关键字static_assert来表示静态断言。使用静态断言,咱们能够在程序的编译时期检测一些条件是否成立。但这个关键字太新了,没有几个编译器是支持的(好像VC2008支持,我用VC不多,主要是在linux下C++编程)。因而可使用C++现有的模板特性来实现静态断言的功能。boost中也已有BOOST_STATIC_ASSERT宏的实现,有兴趣的同窗能够down下来仔细研究一下,它的断言信息更丰富,下面为个人简单实现:spa

 

[c-sharp]  view plain copy
 
  1. // declare a tempalte class StaticAssert.  
  2. template <bool assertion> struct StaticAssert;  
  3.   
  4. // only partial specializate parameter's value is true.  
  5. template <> struct StaticAssert<true>   
  6. {  
  7.   enum { VALUE = 1 };  
  8. };  
  9.  
  10. #define STATIC_ASSERT(expression) (void)StaticAssert<expression>::VALUE   

 

原理是,先声明一个模板类,但后面仅仅偏特化参数值为true的类,而为false的类则一个未定义的类,便是一个未完整的类型,编译期间没法找到StaticAssert<false>::VALUE类型。举例以下:.net

 

[c-sharp]  view plain copy
 
  1. STATIC_ASSERT(4 == sizeof(long) ); //在 32bit机上OK  
  2. STATIC_ASSERT(4 == sizeof(long) ); //在 64bit机上NG,long为8字节  

 

静态断言在编译时进行处理,不会产生任何运行时刻空间和时间上的开销,这就使得它比assert宏具备更好的效率。另外比较重要的一个特性是若是断言失败,它会产生有意义且充分的诊断信息,帮助程序员快速解决问题。debug

相关文章
相关标签/搜索