Assert(断言实现机制剖析)
2013-05-29 11:28
281 查看
Assert(断言实现机制剖析)
原创来自:http://blog.csdn.net/howard58888/article/details/8983418
断言(assert)的作用是用来判断程序运行的正确性,确保程序运行的行为与我们理解的一致。其调用形式为assert(logic expression),如果逻辑表达式为假,则调用abort()终止程序的运行。
查看MSDN帮助文档,可以得到assert的解释信息如下:
[cpp] view
plaincopyprint?
The ANSI assert macro is typically used to identify logic errors during program development, by implementing the expression argument to evaluate to false only when the program is operating incorrectly. After debugging is complete, assertion checking can be turned off without modifying the source file by defining the identifier NDEBUG. NDEBUG can be defined with a /D command-line option or with a #define directive. If NDEBUG is defined with #define, the directive must appear before ASSERT.H is included.
翻译过来大概意思就是assert是通过判断其参数的真假来标识程序的逻辑错误,调试结束后可以通过定义NDEBUG来关闭assert断言。
查看include/assert.h头文件可以得到assert相关的宏写义如下:
[cpp] view
plaincopyprint?
#ifdef NDEBUG
#define assert(exp) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#ifdef __cplusplus
}
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
#endif /* NDEBUG */
解释:
[cpp] view
plaincopyprint?
#ifdef NDEBUG
#define assert(_Expression) ((void)0)//当调试完成后,如果定义了NDEBUG,关闭断言,优化生成的代码
接下来的代码意思是定义如下函数(此函数用于打印出出错信息):
[cpp] view
plaincopyprint?
_wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
有兴趣的可以在assert.c中看到其实现,函数先要把错误的报告模式以及程序的类型(控制台程序还是GUI程序)决定assert是向标准错误输出打印还是以消息框形式出现,最后调用了abort()函数来终止程序的运行。 对于extern “C” 有时间再解释
好了,到最后,终于看到了assert的宏定义了
[cpp] view
plaincopyprint?
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
解释_Expresssion若为false,则!false=true,!true=false,此时继续执行||以后的语句,故会打印出出错信息,终止程序,若_Expression为true,则!true=false,!false=true,此时不再执行||以后的语句,故不会打印出信息。
值得注意的是,里面有一个逗号表达式,有兴趣的可以研究一下,逗号表达式如下
[cpp] view
plaincopyprint?
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0)
asset断言后返回的结果始终是void(1)/void(0),原因就在于逗号表达式。
Assert断言在程序的作用
Assert的例子:
解释:因为tmp=0,tmp==1为false,故程序运行的时候传给assert宏的参数为false,因此调用的结果是先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。如果改成tmp=1,则程序完全正常运行。 如里在程序中想关闭assert宏断言,可以如下defnie NDEBUG
你会发现即出tmp=0,也不会再出现断言信息,解释请看顶部
作用:
1:断言可以用来检查传给函数参数的合法性
[cpp] view
plaincopyprint?
void max(int *a, int n)
{
assert(a!=null)//利用断言确保传给函数的参数不是一个空指针
}
2:一个断言一般只用来检查一个条件,便于分析程序【大师写的<<编程珠玑>>断言的艺术一个断言可以&&与||好几个条件,在我们不是大师之前,还最好不要这样做~~~】
3: 断言前后最好空一格[编程风格的问题,按你自已的喜好,适合自已就最好]
4:断言只是用来检查程序的逻辑正确性,不能代替条件替换
5:断言比printf语句这种形式的打印好使~~~~
6:断言参数可以是函数调用,但是函数返回值要是真假,如assert(sort()),解释看上面源码分析
原创来自:http://blog.csdn.net/howard58888/article/details/8983418
断言(assert)的作用是用来判断程序运行的正确性,确保程序运行的行为与我们理解的一致。其调用形式为assert(logic expression),如果逻辑表达式为假,则调用abort()终止程序的运行。
查看MSDN帮助文档,可以得到assert的解释信息如下:
[cpp] view
plaincopyprint?
The ANSI assert macro is typically used to identify logic errors during program development, by implementing the expression argument to evaluate to false only when the program is operating incorrectly. After debugging is complete, assertion checking can be turned off without modifying the source file by defining the identifier NDEBUG. NDEBUG can be defined with a /D command-line option or with a #define directive. If NDEBUG is defined with #define, the directive must appear before ASSERT.H is included.
翻译过来大概意思就是assert是通过判断其参数的真假来标识程序的逻辑错误,调试结束后可以通过定义NDEBUG来关闭assert断言。
查看include/assert.h头文件可以得到assert相关的宏写义如下:
[cpp] view
plaincopyprint?
#ifdef NDEBUG
#define assert(exp) ((void)0)
#else
#ifdef __cplusplus
extern "C" {
#endif
_CRTIMP void __cdecl _assert(void *, void *, unsigned);
#ifdef __cplusplus
}
#endif
#define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) )
#endif /* NDEBUG */
解释:
[cpp] view
plaincopyprint?
#ifdef NDEBUG
#define assert(_Expression) ((void)0)//当调试完成后,如果定义了NDEBUG,关闭断言,优化生成的代码
接下来的代码意思是定义如下函数(此函数用于打印出出错信息):
[cpp] view
plaincopyprint?
_wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
有兴趣的可以在assert.c中看到其实现,函数先要把错误的报告模式以及程序的类型(控制台程序还是GUI程序)决定assert是向标准错误输出打印还是以消息框形式出现,最后调用了abort()函数来终止程序的运行。 对于extern “C” 有时间再解释
好了,到最后,终于看到了assert的宏定义了
[cpp] view
plaincopyprint?
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
解释_Expresssion若为false,则!false=true,!true=false,此时继续执行||以后的语句,故会打印出出错信息,终止程序,若_Expression为true,则!true=false,!false=true,此时不再执行||以后的语句,故不会打印出信息。
值得注意的是,里面有一个逗号表达式,有兴趣的可以研究一下,逗号表达式如下
[cpp] view
plaincopyprint?
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0)
asset断言后返回的结果始终是void(1)/void(0),原因就在于逗号表达式。
Assert断言在程序的作用
Assert的例子:
解释:因为tmp=0,tmp==1为false,故程序运行的时候传给assert宏的参数为false,因此调用的结果是先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。如果改成tmp=1,则程序完全正常运行。 如里在程序中想关闭assert宏断言,可以如下defnie NDEBUG
你会发现即出tmp=0,也不会再出现断言信息,解释请看顶部
作用:
1:断言可以用来检查传给函数参数的合法性
[cpp] view
plaincopyprint?
void max(int *a, int n)
{
assert(a!=null)//利用断言确保传给函数的参数不是一个空指针
}
2:一个断言一般只用来检查一个条件,便于分析程序【大师写的<<编程珠玑>>断言的艺术一个断言可以&&与||好几个条件,在我们不是大师之前,还最好不要这样做~~~】
3: 断言前后最好空一格[编程风格的问题,按你自已的喜好,适合自已就最好]
4:断言只是用来检查程序的逻辑正确性,不能代替条件替换
5:断言比printf语句这种形式的打印好使~~~~
6:断言参数可以是函数调用,但是函数返回值要是真假,如assert(sort()),解释看上面源码分析
相关文章推荐
- Assert(断言实现机制深入剖析)
- Assert(断言实现机制剖析)
- Assert(断言实现机制剖析)
- Scala:用传名参数实现断言机制及其特点
- cocos2d-x核心类剖析-coco2d-x触屏实现机制
- linux内核剖析---Linux系统调用详解(实现机制分析)
- STM32的断言机制——函数assert_param()
- C++ Assert()断言机制原理以及使用
- Ogre源码剖析:如何实现低耦合的类间消息传递机制
- android 源码剖析之------Window的内部实现机制(添加、删除、更新)
- Linux系统调用详解(实现机制分析)--linux内核剖析(六)
- Storm DRPC实现机制分析剖析
- Android消息处理机制:源码剖析Handler、Looper,并实现图片异步加载
- [置顶] ATL窗口thunk机制的剖析与实现
- Assert断言机制
- c\c++复习基础要点05---assert断言及其自定义实现
- Redis中主键失效的原理及实现机制剖析
- C++的多态性实现机制剖析
- 断言机制assert_param的使用
- Assert断言机制