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


     

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

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

    1 #define MACRO  2

         则:

         1) 查看宏名是否定义

    2 #if defined MACRO
    3     #error defined MACRO!
    4 #endif

         2) 查看宏值是否某值

    5 #if (2 == MACRO)
    6     #error (2 == MACRO)!
    7 #endif

         编译输出:

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

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

     

    2. 编译阶段可知的信息

         定义下述静态断言宏:

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

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

         应用举例如下:

     1 typedef struct{
     2     char acRecord[32];
     3 }T_HIST_ALM;
     4 #define HIS_ALM_NUM   300     //历史告警最大数目
     5 
     6 #define HIS_ALM_BASE  0x3000  //历史告警起始地址
     7 #define HIS_LOG_BASE  0x4000  //历史日志起始地址
     8 
     9 int main(void){
    10     STATIC_ASSERT(sizeof(T_HIST_ALM) <= 20);
    11     STATIC_ASSERT2((HIS_ALM_BASE + sizeof(T_HIST_ALM)*HIS_ALM_NUM) < HIS_LOG_BASE, 
    12                    History_Alarm_Space_Is_Not_Enough);
    13     return 0;
    14 }

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

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

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

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

     

    3. 运行期间可知的信息

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

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

         应用举例如下:

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

         运行时输出:

    1 [test.c(2)<main>]Minus 128 = 0xffffff80!
  • 相关阅读:
    【转】js竖状伸缩导航
    大学易站暂时关闭通知
    【转】神同步!这俩熊孩子太会玩了,以前的同步都弱爆了
    【技术贴】搜狗浏览器 标签页 看后吧 解决
    四级查分步骤解决无法找到对应的分数 请确认你已安装并启动了CET查分保护盾
    解决Mysql远程连接出错不允许访问 ERROR 1130:Host is not allow
    xml 获取节点下的 属性。
    Oracle 获取日期区间数据
    js 数值转换为3位逗号分隔
    xml获取子节点
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/3849113.html
Copyright © 2020-2023  润新知