`

C++ assert机制

 
阅读更多

C++ assert机制

ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。

 

原型定义:
#include <assert.h>
void assert( int expression_r_r_r );

assert的作用是现计算表达式 expression_r_r_r ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。请看下面的程序清单badptr.c:


#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

int main( void )
{
FILE *fp;

fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp );

fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开失败
assert( fp ); //所以这里出错
fclose( fp ); //程序永远都执行不到这里来

return 0;
}

[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: Assertion `fp'' failed.
已放弃

 

使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>

 

用法总结与注意事项:
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++ < 100)
这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。
正确: assert(i < 100)
i++;


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

5)有的地方,assert不能代替条件过滤

 

ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略掉。(在C中,ASSERT是宏而不是函数),使用ASSERT“断言”容易在debug时输出程序错误所在。
assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。

 

原型定义:
#include <assert.h>
void assert( int expression_r_r_r );

assert的作用是现计算表达式 expression_r_r_r ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。请看下面的程序清单badptr.c:


#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

int main( void )
{
FILE *fp;

fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp );

fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开失败
assert( fp ); //所以这里出错
fclose( fp ); //程序永远都执行不到这里来

return 0;
}

[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: Assertion `fp'' failed.
已放弃

 

使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>

 

用法总结与注意事项:
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++ < 100)
这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。
正确: assert(i < 100)
i++;


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

5)有的地方,assert不能代替条件过滤

 

ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略掉。(在C中,ASSERT是宏而不是函数),使用ASSERT“断言”容易在debug时输出程序错误所在。
assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

 

From:http://hi.baidu.com/hins_pan/item/d61b21c1b2efe428ee466554

分享到:
评论

相关推荐

    C++ Assert()断言机制原理以及使用方法

    下面小编就为大家带来一篇C++ Assert()断言机制原理以及使用方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Visual C++2010开发权威指南(共三部分).part1.rar

    1.8.3 静态断言static_assert 17 1.8.4 auto关键字 18 1.8.5 右值引用 19 1.8.6 安全数据类型 22 1.8.7 移动构造 23 1.9 支持开发并行程序 26 1.9.1 运行库支持native代码 26 1.9.2 调试和分析工具 29 1.10 对MFC的...

    详解C++编程中断言static_assert的使用

    C++ 语言支持可帮助您调试应用程序的三个错误处理机制:#error 指令、static_assert 关键字和 assert (CRT) 宏。所有的三种机制都会发出错误消息,其中两个还会测试软件断言。软件断言指定在程序的某个特定点应满足...

    Visual C++2010开发权威指南.part01

    1.8.3 静态断言static_assert 17 1.8.4 auto关键字 18 1.8.5 右值引用 19 1.8.6 安全数据类型 22 1.8.7 移动构造 23 1.9 支持开发并行程序 26 1.9.1 运行库支持native代码 26 1.9.2 调试和分析工具 29 1.10 对MFC的...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    4.3.1 assert宏 111 4.3.2 占位程序和驱动程序 112 第5章 数组 119 5.1 数组简介 119 5.1.1 数组的声明和引用 119 5.1.2 内存中的数组 122 5.1.3 数组的初始化 124 5.2 函数中的数组 125 5.2.1 作为函数...

    C++MFC教程

    ASSERT VERIFY 常用函数 CWindApp* AfxGetApp(); HINSTANCE AfxGetInstanceHandle( ); HINSTANCE AfxGetResourceHandle( ); int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );用于弹...

    xhnet:是由c++编写的一个服务器基础库

    ###1、异常处理机制,dump、异常抛出不直接崩溃程序、lua远程调试机制### ###2、文件日志### ###3、性能检查XH_ACTION_GUARD、XH_ACTION_LOGINFO### ###4、一些小工具md5、iconv、XHGUARD、XH_STACK_TRACE### ###5、...

    最新名企标准通用C++面试题,

    assert((strDest!=NULL) && (strSrc !=NULL));//2分 char *address = strDest;//2分 while( (*strDest++ = * strSrc++) != ‘\0’ )//2分 NULL; return address;// 2分 } 5.1 strcpy能把strSrc的内容复制到...

    c++ 面试题 总结

    assert(NULL != p); sscanf(p, "%s%d", str, n); if (0 == strcmp(str, "something")) { ... } } A: sscanf(p, "%s%d", str, n); 这句该写成: sscanf(p, "%s%d", str, &n); ------------------------------...

    VC++2010权威开发指南+源代码

     1.8.3 静态断言static_assert 17  1.8.4 auto关键字 18  1.8.5 右值引用 19  1.8.6 安全数据类型 22  1.8.7 移动构造 23  1.9 支持开发并行程序 26  1.9.1 运行库支持native代码 26  1.9.2 调试和分析工具 ...

    VC++2010权威开发指南+源代码.part2

     1.8.3 静态断言static_assert 17  1.8.4 auto关键字 18  1.8.5 右值引用 19  1.8.6 安全数据类型 22  1.8.7 移动构造 23  1.9 支持开发并行程序 26  1.9.1 运行库支持native代码 26  1.9.2 调试和分析工具 ...

    详解C++中的内存同步模式(memory order)

    内存模型中的同步模式(memory model synchronization ...不同的内存同步模式标识了线程间数据共享机制的”强弱”程度,富有经验的程序员可以使用”较弱”的同步模式来提高程序的执行效率. 每一个原子类型都有一个 load()

    我的编程感悟(中文PDF)(共37M二分卷)分卷二

    11.6.4 回调机制 336 11.7 反外挂技术 338 11.7.1 防止加速器 338 11.7.2 防止分析伪造网络包 339 11.7.3 防止逆向工程 341 11.7.4 防止代码钩子 344 11.7.5 惩戒外挂作弊者 344 11.7.6 安全地将信息传递给服务器 ...

    我的编程感悟(中文PDF)(共37M二分卷)分卷一

    11.6.4 回调机制 336 11.7 反外挂技术 338 11.7.1 防止加速器 338 11.7.2 防止分析伪造网络包 339 11.7.3 防止逆向工程 341 11.7.4 防止代码钩子 344 11.7.5 惩戒外挂作弊者 344 11.7.6 安全地将信息传递给服务器 ...

Global site tag (gtag.js) - Google Analytics