您的位置:首页 > 编程语言 > C语言/C++

C++ assert

2015-10-22 18:33 225 查看

用法:

先包含

#inlcude <assert.h>

在想用的地方给一句:

assert(expression)就可以了。

expression是任意有效的逻辑表达式。

比如:

FILE *fp = fopen("in.txt","r") ;

if ( ! fp ){

exit(0) ;

}

assert(fp != NULL) ;

当expression不满足时,就会报出一个很丑陋的框框,

然后向控制台输出assert不满足的文件和行号。

具体到debug的时候,

可以撒网式地在各个地方放上认为应该为真的表达式的assert,

说不定哪个就爆了,于是趁机发现了问题。

原理:

只要有源码就没有秘密,

所以打开assert.h,看看里面是怎么写的。

主要的就这两句:

_CRTIMP void __cdecl _assert(void *, void *, unsigned);

#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )

第一句就干的就是输出一些信息,然后弹出个框框,

顺便结束程序这些勾当。

他被调用的时候,是类似于:

_assert("false" , "c:\\1.cpp" , 15)

这样。

第二句的构造可谓精简啊,小小一句话还包含了挺多以前没注意到的事情。

1.短路求值

这个是c的重要特性,在处理&&的时候前面为假则不用继续,

在处理|| 的时候,前面为真则不用继续。

形象地说把后面的表达式短路了。

2.单行宏

#exp 生成"exp"这样的字符串

#@a 生成'a'这样的字符

a##b 把a和b连接起来

第一个用法在这里见到了,第二个暂时还没见到用的实例。

第三个在a和b是宏的参数的时候有用。否则直接的ab会被当作一个东西。

3.特殊的预定义宏

__FILE__ 会被替换成所在的文件,字符串形式

__LINE__ 会被替换成行号,unsigned类型

__DATE__ 会被替换成日期

__TIME__ 会被替换成时间

其实之前翻过的跟C有关的书应该都讲了这些的。

不过拿着一个列表,又不给出真正实用的例子,

当然不知道这些东西是怎么回事,

久了自然也就忘了。

4.逗号表达式

感觉实在是一个用的很少的事情,

毕竟有多句话的时候,完全可以用分号就行了。

虽然有好多地方在if之类的里面很压缩的用逗号表达式写好几句话,

其实都可以改得不用逗号表达式的。

其一是逗号表达式的优先级很低,所以后面那对括号实在是不可缺少。

其二是逗号表达式的值为最右边式子的值。

这个估计很多人都记过,但不见得有啥重大意义。

这里,倒确实是发挥了他的意义。

因为_asert这个函数是void型的,

如果不使用逗号表达式在右边补个0的话,

会报告:(VC6)

error C2297: '||' : illegal, right operand has type 'void'

改编:

知道是怎么回事,当然可以很容易做出自己想要的东西。

再说还有asert.h里面的参照呢。

比如,我嫌默认的_assert弹出的东西看着太压抑了。。。

就自己写个就行了。

#include <windows.h>

#include <stdio.h>

#include <stdlib.h>

#define MAX_BUFFER 200

void _assert(char *msg , char *file , unsigned line){

char buf[MAX_BUFFER] ;

sprintf(buf , "assertion fail:\n%s\nin file:\n%s\non line:\n%d" , msg , file , line) ;

::MessageBox(NULL , buf , "assertion failure" , MB_OK) ;

exit(0) ;

}

#define assert(exp) ((exp) || (_assert(#exp , __FILE__ , __LINE__) , 0) )

int main(){

assert(1 == 1 && 3 == 4) ;

return 0 ;

}

反正通过简单变更_assert函数,可以把相关情况输出到文件,

或者选择另外的方式表达出来,能想到的都可以。

至于assert这个宏,也有可以动手脚的地方。

自带的是assert一个为真的表达式。

有的时候就想assert一个为假的表达式,当他为真的时候发出警告。

比如:

FILE *fp = fopen("in.txt","r") ;

if ( ! fp ){

exit(0) ;

}

warn(fp == NULL)

套用上面的写法,既然是为真发警告,那么用&&去换||就行了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: