首先assert()和sizeof一样,并不是函数,而是一个宏。assert宏的原型定义在中:#include
//Linux下的定义
void assert(scalar expression);
//VS里面的定义
#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
Linux下的man文档是这样描述的:If the macro NDEBUG was defined at the moment was last included, the macro assert() generates no code, and hence does nothing at all. Otherwise, the macro assert() prints an error message to standard error and terminates the program by calling abort(3) if expression is false (i.e., compares equal to zero).
The purpose of this macro is to help the programmer find bugs in his program. The message "assertion failed in file foo.c, function do_bar(), line 1287" is
of no help at all to a user.
大概意思已经说得很明确了:
如果在(最后一次)包含文件的时候,如果没有使用NDEBUG宏,那么当assert的参数表达式为假的时候,assert就会向标准输出打印一条错误消息,并且调用abort()函数来终止程序。相反,如果定义了NODEBUG宏,那么assert并不生成任何代码,也就是什么也不做。
这个宏的作用呢也是帮助程序员找到程序的bug,输出信息对于用户来说是毫无用处的。
注意:在C89中,expression必须是整型的,否则assert的行为是未知的。但是在C99中,expression可以是任何标量类型。
下面用一个例子来说明assert的用法:#include
#include
#include
int main()
{
FILE *fp;
fp = fopen("test1.txt", "w"); //以可写的方式打开一个文件,如果不存在则创建一个,所以此处fp不会为NULL
assert(fp); //因为fp不会为NULL,也即不为假,所以此处不会出错
fclose(fp);
fp =fopen("test2.txt", "r"); //以只读方式打开test2.txt文件,假设该文件不存在,则打开失败,fp为NULL
assert(fp); //fp为NULL,即为假,此处出错。assert会打印出错信息,并调用abort终止程序。
fclose(fp);
return 0;
}
assert使用虽然非常方便,可以很容易的定位程序的bug,但是频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在#include 语句之前插入#define NDEBUG来禁用assert调用。另外,assert在程序的Release版本中是无效的。