/*说明:
assert 其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
如果加了-DNDEBUG 等于去掉了assert函数。
*/
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <signal.h>
#define AV_STRINGIFY(s) AV_TOSTRING(s)
#define AV_TOSTRING(s) #s ///c语言函数会强制把这个s表达式转为字符串。
#define av_assert0(cond) do { \
if (!(cond)) { \
printf("Assertion %s failed at %s:%d\n", \
AV_STRINGIFY(cond), __FILE__, __LINE__); \
abort(); \
} \
} while (0)
void sig_handler(int sig)
{
fprintf(stderr,"have called abort(),app exit!\n");
exit(0);
}
int main( void )
{
int test;
test=5;
signal(SIGABRT,sig_handler);///验证是否调用了abort
FILE *fp;
fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp );
fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开文件失败
///assert( fp ); //所以这里出错
av_assert0(test==6); 这里测试ffmpeg中定义的assert函数。
fclose( fp ); //程序永远都执行不到这里来
return 0;
}
/*----------------------------
测试1,没有使用-DNDEBUG 编译:
gcc test_assert.c -o test_noDEBUG
sno@sno-desktop:~/little_test$ ./test_noDEBUG
test_noDEBUG: test_assert.c:12: main: Assertion 'fp' failed.
已放弃
-----------------------------
测试2,使用 定义的宏:-DNDEBUG
gcc test_assert.c -o test_useDEBUG -DNDEBUG
sno@sno-desktop:~/little_test$ ./test_useDEBUG
段错误
----------------------
测试3,测试ffmpeg中定义的assert:
sno@sno-desktop:~/little_test$ gcc test_assert.c -o test_assert
sno@sno-desktop:~/little_test$ ./test_assert
Assertion test==6 failed at test_assert.c:42 ///通过这一句可以看出,宏定义中的__LINE__就是一整条语句,直接加在定义的那一行。
have called abort(),app exit!
------------------------------------------------------
结果:
看man手册的解释:
If the macro NDEBUG was defined at the moment <assert.h> was last
included, the macro assert() generates no code, and hence does nothing
at all. Otherwise, the macro assert() prints an error message to stan‐
dard 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.
第二段说的不错,这个宏只是帮助programmer查找bugs,对用户是没有用处的。
结论:
在调试的时候,加上这个assert语句,在release版本的时候,加上-DNDEBUG选项,等于去掉assert语句。
*/