我记得在以前的一篇随笔中,我堆windows下的<assert.h>进行了分析,今天我们来看看gcc中这个文件的定义是怎样的。

【1】assert宏的作用

  assert宏实现断言的作用,一般在源文件中引用格式如下:

#include <assert.h>

#undef NDEBUG
assert(expression)

关于assert宏:

  1、当 expression的值为0时进行断言,如果表达式expression的值非零,则不进行断言。

  2、assert宏进行断言的时候,在标准错误输出中输出断言发生的源文件名称:__FILE__ 和断言发生时语句所在的行: __LINE__

  3、可在程序的调试过程中,利用assert宏进行关键点程序进行测试,以输出一些有用的信息,当不需要调试的时候,可以通过定义NDEBUG宏来取消

宏assert的作用。

【2】assert.h

/* Allow this file to be included multiple times
   with different settings of NDEBUG.  */

//assert 为C库提供的一种断言机制
//断言用来在标准错误输出流输出信息,并且使程序异常终止
/*
    断言的机制:

*/

//首先取消 assert 宏的定义,
//这样做的目的是为了防止宏重复被定义
#undef assert
#undef __assert

//通过判断是否定义宏 NDEBUG 来判断在源代码中是否需要宏assert
/*
    如果定义了 NDEBUG 宏,就表示不需要在程序中引用 assert 宏
    NDEBUG: do not debug
    否则就在程序中,assert 宏将被执行

    可以发现assert宏在定义 NDEBUG时,定义很特别,宏参数并没有引用
*/
#ifdef NDEBUG
    //定义了NDEBUG宏,assert 宏定义为不做任何提示输出
     #define assert(ignore)  ((void)0)
#else
    void __eprintf ();        /* Defined in gnulib */
    #ifdef __STDC__    //定义了__STDC__宏
        #define assert(expression)  \
              ((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
        #define __assert(expression, file, lineno)  \
              (__eprintf ("Failed assertion `%s' at line %d of `%s'.\n",    \
                  expression, lineno, file), 0)
    #else /* no __STDC__; i.e. -traditional.  */
        #define assert(expression)  \
              ((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
        #define __assert(expression, file, lineno)  \
              (__eprintf ("Failed assertion `%s' at line %d of `%s'.\n",    \
                  "expression", lineno, file), 0)
    #endif /* no __STDC__; i.e. -traditional.  */
#endif
View Code

相关文章: