• C语言学习趣事_20_Assert_Setjmp


      最近看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;
    }



  • 相关阅读:
    iphone 自学常用网址
    @ApiParam @RequestParam @PathVariable 用法
    @RestController 与 @Controller 注解区别
    Java:post请求
    Java:清空文件内容
    Java:追加文件内容
    Java:获取文件内容
    Java:Md5加密
    Java:获取IP地址
    docker:安装tomcat
  • 原文地址:https://www.cnblogs.com/volcanol/p/2346754.html
Copyright © 2020-2023  润新知