zoukankan      html  css  js  c++  java
  • 获取代码中宏定义等信息的一些手段

    获取代码中宏定义等信息的一些手段

    来源 https://www.cnblogs.com/clover-toeic/p/3849113.html

    1.  预编译阶段可知的信息

         假设代码某处有宏定义如下:

    #define MACRO  2

         则:

         1) 查看宏名是否定义

    #if defined MACRO
        #error defined MACRO!
    #endif

         2) 查看宏值是否某值

    #if (2 == MACRO)
        #error (2 == MACRO)!
    #endif

         编译输出:

    test.c:3:10: error: #error defined MACRO!
    test.c:6:10: error: #error (2 == MACRO)!

         其中,#error用于输出自定义的预处理信息,并非指示真实出现的错误。

     

    2. 编译阶段可知的信息

         定义下述静态断言宏:

    #define CONCATE(x, y)             _CONCATE(x, y)
    #define _CONCATE(x, y)            x##y
    #define STATIC_ASSERT(exp)        typedef char 
         CONCATE(Assertion_Failed_at_Line, __LINE__)[(exp) ? 1 : -1]
    #define STATIC_ASSERT2(exp, str)  typedef char 
         CONCATE(str##_at_Line, __LINE__)[(exp) ? 1 : -1]

         该宏巧妙地利用gcc编译器下数组下标为-1时的编译报错。其中,exp为需要检查的表达式;str为用户定制的错误信息字符串,须满足C语言变量命名规则(不要写成字符串或带空格或以数字起始等)。typedef char意在避免变量命名冲突或命名空间污染。

         应用举例如下:

    typedef struct{
        char acRecord[32];
    }T_HIST_ALM;
    #define HIS_ALM_NUM   300     //历史告警最大数目
    
    #define HIS_ALM_BASE  0x3000  //历史告警起始地址
    #define HIS_LOG_BASE  0x4000  //历史日志起始地址
    
    int main(void){
        STATIC_ASSERT(sizeof(T_HIST_ALM) <= 20);
        STATIC_ASSERT2((HIS_ALM_BASE + sizeof(T_HIST_ALM)*HIS_ALM_NUM) < HIS_LOG_BASE, 
                       History_Alarm_Space_Is_Not_Enough);
        return 0;
    }

         编译后报错如下(示例代码中省略头文件和断言宏定义,故行号显示有所出入):

    [wangxiaoyuan_@localhost test1]$ gcc -o test test.c
    test.c: In function 'main':
    test.c:17: error: size of array 'Assertion_Failed_at_Line17' is negative
    test.c:18: error: size of array 'History_Alarm_Space_Is_Not_Enough_at_Line19' is negative

         可见,编译报错本身已提供文件名、函数名和行号信息,故断言宏内的行号可有可无。

         静态断言可用于编译期间检查数组、堆等缓冲区溢出,以及资源分配是否足够等。

     

    3. 运行期间可知的信息

         定义调试跟踪宏,在待日志信息前附加日志文件名、行数、函数名等信息:

    #define TRACE(fmt, args...) do{
        printf("[%s(%d)<%s>]", __FILE__, __LINE__, __FUNCTION__);
        printf((fmt), ##args);
    }while(0)

         应用举例如下:

    int main(void){
        TRACE("Minus 128 = 0x%x!
    ", -128);               
        return 0;
    }

         运行时输出:

    [test.c(2)<main>]Minus 128 = 0xffffff80!

    ================ End

  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/11696019.html
Copyright © 2011-2022 走看看