volcanol的工控博客
Email : lilinly225@126.com 索要资料加QQ 点击进入 或 点击左侧的资料分享专用帖

volcanol ---- View OF Linux Can Appreciate Nature OF Linux

天行健,君子以自强不息

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

  最近看C库,简单的学习了一下assert和setjmp库的功能,贴点心得。

/*
本程序测试库函数,用来学习、理解库
*/

#include <stdio.h>
/*
测试:assert宏 与 NDEBUG的关系
Tip:
经过各种测试,为了取消 assert 宏,必须在它之前定义NEDBUG;
这里也说明一个问题,宏的定义和引用是有先后顺序的
如果
#undef NDEBUG
#define NDEBUG

#include <assert.h> 之后定义 NDEBUG 宏,那么就不能取消assert宏

这里有一个比较特殊的性能,无论某个宏是否被定义,都可以用#undef 来取消它。
*/
#undef NDEBUG
#define NDEBUG
#include <assert.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>



/*
测试setjmp标准头文件

<setjmp.h>头文件功能:
用来实现非模块化函数编程。

数据类型:jmp_buf
#define _JBLEN 16
#define _JBTYPE int
typedef _JBTYPE jmp_buf[_JBLEN];
这里可以看出:
jmp_buf: 为一个 int [16] 类型
宏 setjmp(jmp_buf env)
setjmp(jmp_buf env) 是一个宏定义,用来代替set_jmp 函数;
这个宏用来设置 env 变量, env变量存储设定位置行的程序地址;
设置时返回 0;
当执行longjmp函数的时候,就从set_jmp设置的位置开始执行,并且
再次从设定位置执行的时候 set_jmp 宏返回longjup指定的值。
函数 longjmp(jmp_buf env, int val)
函数导致程序执行结构跳转到 setjmp 设置的 env 地址处执行,并且
设定再次执行 env 地址处的函数时 setjmp 宏的返回值。
Tip:
注意利用这个特性会破坏模块化的编程结构,这个用法主要用于处理
低级操作时的严重错误。

*/
static jmp_buf buf;
void test_jmp_fun(void)
{
/*
如果去掉static的话,则这个函数打印随即的值
如果保留static的话,则打印 5 。
并且会在输出 :
puts("Set_jmp call:\n");后输出5
*/
volatile static int i_test;

i_test=3;

if( setjmp(buf) == 1 )
{
printf("%d\n",i_test);
exit(0);
}

i_test=5;
}


int main(int argc,char *argv[])
{
int i_assert;

i_assert=0;


/*
测试 assert 宏
用法:
#include <assert.h>
void assert(int expression)
功能:
assert宏测试 expression 的值,如果expression的值 =0;则
异常中断程序,并且输出一些信息;包括 表达式的文本、源文件
的名字(包括路径)、和出错行在原文本中的行数。
后两者分别是:
_FILE_ 宏

_LINE_ 宏
的值。
当执行完前面的操作后,就退出程序的执行。
*/
assert(i_assert);

/*
测试编译器预定义的宏:
__FILE__ : 不需要包含头文件,这个预定义的宏,由编译器负责解释,
它表示源文件的名字,包括路径。
__LINE__: 不需要包含头文件,这个预定义的宏,由编译器负责解释,
由它表示这个宏所在的行数。
*/
puts(__FILE__);
printf("This line is %d th line.\n",__LINE__);


printf("The max value is %d\n",max(3,5));


test_jmp_fun();
puts("Set_jmp call:");
longjmp(buf,1);


return 0;
}

下面是引用的另外一个文件,下面的注释部分是VS 2008的编译信息,可以发现连接之前,max为未定义的标识符。

/*
1>------ Rebuild All started: Project: LibTest, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'LibTest', configuration 'Debug|Win32'
1>Compiling...
1>main.c
1>g:\03_c_code_exp\libtest\libtest\main.c(75) : warning C4013: 'max' undefined; assuming extern returning int
1>test.c
1>Generating Code...
1>Compiling manifest to resources...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Linking...
1>LINK : G:\03_C_Code_Exp\LibTest\Debug\LibTest.exe not found or not built by the last incremental link; performing full link
1>Embedding manifest...
1>Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://g:\03_C_Code_Exp\LibTest\LibTest\Debug\BuildLog.htm"
1>LibTest - 0 error(s), 1 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
*/
int max(int x,int y)
{
return x>y?x:y;
}



posted on 2012-02-11 15:54  volcanol  阅读(1698)  评论(4编辑  收藏  举报
volcanol ----View OF Linux Can Appreciate Nature OF Linux。