获取代码中宏定义等信息的一些手段
获取代码中宏定义等信息的一些手段
来源 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!\n", -128); return 0; }
运行时输出:
[test.c(2)<main>]Minus 128 = 0xffffff80!
================ End
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-10-18 灵修书籍
2018-10-18 体瘾到底是什么
2017-10-18 一个简单的类模板的友元函数和友元类示例
2017-10-18 Linux CentOS7 安装 Qt 5.9.2