C 断言(assert)使用
通过一个例子来说明
#include <stdio.h>
#include <assert.h>
int main(int argc, char* argv[])
{
int i = 1;
assert(i>0);
printf("i=%d\n", i);
return 0;
}
$ gcc -E assert.c -o assert.E
$ gcc -DNDEBUG -E assert.c -o assert_NODEBUG.E
assert.E
...
# 4 "assert.c"
int main(int argc, char* argv[])
{
int i = 1;
# 7 "assert.c" 3 4
((void) sizeof ((
# 7 "assert.c"
i>0
# 7 "assert.c" 3 4
) ? 1 : 0), __extension__ ({ if (
# 7 "assert.c"
i>0
# 7 "assert.c" 3 4
) ; else __assert_fail (
# 7 "assert.c"
"i>0"
# 7 "assert.c" 3 4
, "assert.c", 7, __extension__ __PRETTY_FUNCTION__); }))
# 7 "assert.c"
;
printf("i=%d\n", i);
return 0;
}
((void) sizeof (( i>0 ) ? 1 : 0),
__extension__ (
{
if ( i>0 )
;
else __assert_fail ( "i>0" , "assert.c", 7, __extension__ __PRETTY_FUNCTION__);
}
)
);
sizeof(1 or 0)等于同sizeof(int),这句没有什么实际意义,最终编译结果中这句会被忽略丢弃并不产生任何指令操作。
GCC对ANSI C标准进行了扩展,使用这些扩展时,编译器会抛出警告。使用__extension__
关键字告诉GCC不要抛出警告。
assert_NODEBUG.E
...
# 4 "assert.c"
int main(int argc, char* argv[])
{
int i = 1;
# 7 "assert.c" 3 4
((void) (0))
# 7 "assert.c"
;
printf("i=%d\n", i);
return 0;
}
assert函数其实是一个宏,它只在DEBUG编译模式下有效。
assert 的作用是现计算表达式,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。
使用 assert 的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。