头文件<assert.h>唯一的目的就是提供assert宏定义,可以在程序中关键的地方使用这个宏来进行断言。如果一处断言被证明非真,希望程序在标准错误流输出一条适当的提示信息,并使执行异常终止。

它的原型如下:

void assert( int expression );

当它被执行时,这个宏对表达式参数进行测试。如果它的值为假(0),它就向标准错误打印一条诊断信息并终止程序。这条信息的格式是由编译器定义的,但它将包含这个表示式和源文件的名字以及断言所在的行号。(后面会给出具有案例) 如果表达式为真,它将不打印任何东西,程序继续执行。

注:由于assert()不是一个函数而是一个宏,所以assert实际上并不具有原型,但是,这个原型可以形象的说明assert的用法。

这个宏提供了一个方便的方法,对应该是真的东西进行检查。例如,一个函数必须用一个不能为 NULL 的指针参数进行调用,那么函数可以用assert验证这个值:

assert( value != NULL );

如果函数错误的接受了一个 NULL 参数,程序将会打印一条类似下面的信息:

Assertion failed: value != NULL, file.c line 274

提示:用这种方法使用assert使调试变得更容易,因为一旦出现错误,程序就会停止。而且,这条信息准确地提示了症状出现的地点。如果没有断言,程序可能继续执行,并在以后失败,这就很难调试了。

注意 assert 只适用于验证必须为真的表达式。由于它会终止程序,所以你无法用它检查那些你试图进行处理的情况,例如检查非法的输入并要求用户重新输入一个值。

当程序被完整地测试完毕之后,你可以在编译时通过定义 NDEBUG 消除所有的 assert. 你可以在源文件的头文件中 assert.h 被包含之前增加下面这个定义:

#define NDEBUG

当NDEBUG 被定义之后,预处理器将丢弃所有的 assert,这样就消除了这方面的开销,而不必在源文件中把所有的assert实际删除!

(可以通过在程序的某些地方定义宏NDEBUG来改变assert的展开方式

如果程序某个包含assert的地方没有定义NDEBUG,该头文件就会将宏assert定义为活动形式,它就可以展开为一个表达式,测试断言并在断言为假的时候输出一条错误信息,然后程序终止。反之,如果定义了NDEBUG,头文件就会把这个宏定义为不执行任何操作的静止形式。)

参考:《c与指针》

assert