当前位置: 首页 > news >正文

代码技巧:X-MACRO 技术,减少无谓的代码重复 - Flandre

前言

我是在做南京大学 ICS-PA 的时候学会的这个

写过的同学都知道这里面有非常多奥妙重重的宏定义,值得我们学习

下面,正片开始

使用场景引入

看一个例子:假如我们有若干个名字和 ID 的对应,实际情景中是 (学过计组的可以看出这个是 RISCV 中规定的 CSR 及其 id)

MTVEC: 0x305
MSTATUS: 0x300
MEPC: 0x341
MCAUSE: 0x342
SATP: 0x180

我们有多处代码,都要用到这个对应关系。比如

(1)
const char *csr_reg_names[4096] = {[0x305] = "MTVEC",[0x300] = "MSTATUS",[0x341] = "MEPC",[0x342] = "MCAUSE",[0x180] = "SATP"
};(2)
const int csr_reg_id[] = {0x305, 0x300, 0x341, 0x342, 0x180};(3)
enum { MTVEC = 0x305, MSTATUS = 0x300, MEPC = 0x341, MCAUSE = 0x342, SATP=0x180};

可以看到它们虽然长得样子不一样,但都用的是同一份 “关系”

如果我们要加入一个新的名字和id的对应,则要改三份代码

我们现在希望只写一份 “原始数据”,并且在每个地方用这个原始数据就行了,该怎么办呢?

解决:X-MACRO 技术

X-MACRO 技术做的事情就是,先写一个公用的 .h 文件(比如叫做 data.h),里面写:

MACRO(MTVEC,   0x305)
MACRO(MSTATUS, 0x300)
MACRO(MEPC,    0x341)
MACRO(MCAUSE,  0x342)
MACRO(SATP,    0x180)

然后在每次使用的时候,对 MACRO 进行定义,在数据主体的部分 #include "data.h",结束了以后 #undef MACRO

比如上面的三个例子,可以写成:

(1)
#define MACRO(NAME,ID) [ID]=#NAME,
// 这个 #NAME 代表给 NAME 周围加上引号, 变成字符串
const char *csr_reg_names[4096] = {#include "data.h"
};
#undef MACRO(2)
#define MACRO(NAME,ID) ID,
const int csr_reg_id[] = {
#include "data.h"
};
#undef MACRO(3)
#define MACRO(NAME,ID) NAME=ID,
enum {
#include "data.h"
};
#undef MACRO

这样虽然代码看起来有点不直观,但方便维护 (如果希望兼顾可读性,可以加注释,这不是问题)

后期,如果要添加更多NAME和ID,只要在 data.h 里面改一次就行了!

http://www.jsqmd.com/news/374862/

相关文章:

  • 基于AT89S52单片机的金属探测器设计
  • 如何在 iPad/iPhone 上删除语音邮件?
  • 国产化GPU调研
  • 强烈安利!千笔AI,好评如潮的降AIGC平台
  • QProcess 执行脚本和命令
  • 2026企业知识管理部署推荐:主流厂商、专属服务商、全案方案商齐全 - 品牌2025
  • 基于单片机温控风扇的设计
  • 用过才敢说 AI论文平台 千笔·专业学术智能体 VS 文途AI,继续教育写作更省心!
  • Java计算机毕设之基于java的粮库设备维护管理系统基于springboot的粮库设备管理系统设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 题解:P14325 [JOI2022 预选赛 R2] 图书馆 2 / Library 2
  • 闲置京东e卡(卡密)回收不用愁!3种常用方法拆解,新手也能轻松变现 - 京回收小程序
  • 5分钟搞定1000套系统巡检!全自动输出可直接上交的 Word 报告
  • 计算机毕业设计之springboot住院部医疗信息管理系统
  • 2026 陕西全屋装修设计甄选指南 五大优质品牌推荐(全包装修实操参考) - 深度智识库
  • JVM参数
  • 2026年全国餐饮酒店设备回收厂家哪家靠谱?适配各类门店与业态需求 - 深度智识库
  • 阳光房遮阳帘常见问题解答:10个核心疑问全解析 - 速递信息
  • 2026年全国餐饮酒店设备回收厂家权威榜单 适配各类酒店餐饮业态 多场景高效处置 - 深度智识库
  • 实用指南:iOS Swift MVVM + RxSwift Generic Rules
  • 计算机Java毕设实战-基于springboot的小学阶段图形化编程竞赛辅导网站设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 港华商会与碳启元合作,为绿色商业发展注入新动力
  • 银川办公楼装修选哪家?本地专注工装老品牌,适配全规模企业需求 - 宁夏壹山网络
  • 计算机Java毕设实战-基于springboot的粮库设备巡检,维修,报修管理系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 改稿速度拉满!千笔,专科生降AI率首选工具
  • 基于C#和周立功USBCAN设备的完整上位机开发示例
  • 计算机Java毕设实战-基于springboot的停车场收费管理系统设计与实现基于 SpringBoot 的社区物业车位收费管理系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 题解:P14167 [Algo Beat Contest 002.5 B] 草莓小蛋糕 (cakes)
  • 从“抽卡“到“导演“——如何构建AI视频生成的母提示词系统
  • 【课程设计/毕业设计】基于springboot的粮库设备维修安检管理系统设计与实现【附源码、数据库、万字文档】
  • 实用指南:如何在mac m1模拟鼠标与键盘的自动化操作