断言(assert)的用法

发布日期:2019-07-23 19:42:22 阅读数: 482次 来源: 作者:

我不断认为 assert 仅仅是个报错函数,现实上,它竟然是个宏,而且感化并非"报错"。

在颠末对其进行必然领会之后,对其感化和用法有了必然的领会,assert() 的用法像是一种"契约式编程",在我的理解中,其表达的意义就是,法式在我的假设前提下,可以或许一般优良的运作,其实就相当于一个 if 语句:

if(假设成立)
{
     法式一般运转;
}
else
{
      报错&&终止法式!(避免由法式运转惹起更大的错误)  
}

可是如许写的话,就会有无数个 if 语句,以至会呈现,一个 if 语句的括号从文件头到文件尾,而且大大都环境下,我们要进行验证的假设,只是属于偶尔性事务,又或者我们仅仅想测试一下,一些最坏环境能否发生,所以这里有了 assert()。

assert 宏的原型定义在 assert.h 中,其感化是若是它的前提前往错误,则终止法式施行。

#include "assert.h" 
void assert( int expression );

assert 的感化是现计较表达式 expression ,若是其值为假(即为0),那么它先向 stderr 打印一条犯错消息,然后通过挪用 abort 来终止法式运转。

利用 assert 的错误谬误是,屡次的挪用会极大的影响法式的机能,添加额外的开销。

在调试竣事后,能够通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 挪用,示例代码如下:

#include 
#define NDEBUG 
#include

用法总结与留意事项

1)在函数起头处查验传入参数的合法性

如:

int resetBufferSize(int nNewSize) 
{ 
//功能:改变缓冲区大小, 
//参数:nNewSize 缓冲区新长度 
//前往值:缓冲区当前长度 
//申明:连结原消息内容不变 nNewSize<=0暗示断根缓冲区 
assert(nNewSize >= 0); 
assert(nNewSize <= MAX_BUFFER_SIZE); 
 
... 
}

2)每个assert只查验一个前提,由于同时查验多个前提时,若是断言失败,无法直不雅的判断是哪个前提失败

     

欠好:

assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize); 
    

好:

assert(nOffset >= 0); 
assert(nOffset+nSize <= m_nInfomationSize); 

3)不克不及利用改变情况的语句,由于assert只在DEBUG个生效,若是这么做,会利用法式在真正运转时碰到问题

错误: assert(i++

这是由于若是犯错,好比在施行之前i=100,那么这条语句就不会施行,那么i++这条号令就没有施行。

准确:

assert(i < 100)
i++; 

4)assert和后面的语句应空一行,以构成逻辑和视觉上的分歧感

  

5)有的处所,assert不克不及取代前提过滤   

  

法式一般分为Debug 版本和Release 版本,Debug 版本用于内部调试,Release 版本刊行给用户利用。断言assert 是仅在Debug 版本起感化的宏,它用于查抄"不该该"发生的环境。以下是一个亚博手机app内存复制法式,在运转过程中,若是assert 的参数为假,那么法式就会中止(一般地还会呈现提醒对话,申明在什么处所激发了assert)。

以下是利用断言的几个准绳:

  • (1)利用断言捕获不该该发生的不法环境。不要混合不法环境与错误环境之间的区别,后者是必然具有的而且是必然要作出处置的。
  • (2)利用断言对函数的参数进行确认。
  • (3)在编写函数时,要进行频频的考查,而且自问:"我筹算做哪些假定?"一旦确定了的假定,就要利用断言对假定进行查抄。
  • (4)一般教科书都激励法式员们进行防错性的法式设想,但要记住这种编程气概会坦白错误。当进行防错性编程时,若是"不成能发生"的工作简直发生了,则要利用断言进行报警。

ASSERT ()是一个调试法式时经常利用的宏,在法式运转时它计较括号内的表达式,若是表达式为FALSE (0), 法式将演讲错误,并终止施行。若是表达式不为0,则继续施行后面的语句。这个宏凡是本来判断法式中能否呈现了较着不法的数据,若是呈现了终止法式免得导致严峻后果,同时也便于查找错误。

ASSERT 只要在 Debug 版本中才无效,若是编译为 Release 版本则被忽略。

本文由亚博编辑整理亚博手机app