基于X Macro生成故障分类枚举与跳转表的技术咨询
基于X Macro实现无重复故障分类枚举与函数跳转表
1. 生成无重复的故障分类枚举
X宏默认会展开所有表项,直接生成枚举会出现重复的分类值。我们可以借助预处理器的“已定义检查”来过滤重复项,具体实现如下:
// 辅助宏:仅当分类未被处理过时,输出枚举项并标记为已处理 #define GENERATE_CATEGORY_ENUM(name, category, action) \ #ifndef ENUM_##category \ category, \ #define ENUM_##category \ #endif // 生成无重复的故障分类枚举 typedef enum { FAULT_TABLE(GENERATE_CATEGORY_ENUM) FAULT_CATEGORY_MAX // 可选:作为枚举的边界值,用于合法性检查 } FaultCategory; // 清理临时定义的宏,避免污染全局命名空间 #undef ENUM_FAULT_CATEGORY_NONE #undef ENUM_FAULT_CATEGORY_1
原理:GENERATE_CATEGORY_ENUM宏会为每个分类生成一个ENUM_XXX的临时宏定义,后续遇到相同分类时,因为ENUM_XXX已定义,会跳过枚举项的输出,从而实现去重。
2. 生成故障码到处理函数的跳转表
根据需求,我们可以实现两种跳转表方案:直接映射故障码到动作函数,或者先映射故障码到分类、再映射分类到动作函数。
方案一:直接生成故障码→动作函数的跳转表
先定义故障码枚举,再通过X宏直接生成对应动作的映射表:
// 第一步:生成故障码枚举 #define GENERATE_FAULT_ENUM(name, category, action) name, typedef enum { FAULT_TABLE(GENERATE_FAULT_ENUM) FAULT_MAX // 故障码边界值 } FaultCode; #undef GENERATE_FAULT_ENUM // 定义故障处理函数的类型 typedef void (*FaultActionFunc)(void); // 第二步:生成故障码到动作函数的跳转表 const FaultActionFunc fault_action_table[] = { #define GENERATE_ACTION_TABLE(name, category, action) action, FAULT_TABLE(GENERATE_ACTION_TABLE) #undef GENERATE_ACTION_TABLE }; // 使用示例:根据故障码执行对应动作 void handle_fault(FaultCode code) { if (code < FAULT_MAX) { fault_action_table[code](); } }
方案二:故障码→分类→动作函数的分层映射
这种方案更适合后续修改分类对应的动作,只需改动分类到动作的映射表,无需修改X宏:
// 第一步:生成故障码到分类的映射表 const FaultCategory fault_to_category[] = { #define GENERATE_FAULT_TO_CATEGORY(name, category, action) category, FAULT_TABLE(GENERATE_FAULT_TO_CATEGORY) #undef GENERATE_FAULT_TO_CATEGORY }; // 第二步:生成分类到动作函数的映射表(利用无重复的分类枚举) const FaultActionFunc category_action_table[] = { [FAULT_CATEGORY_NONE] = action_none, [FAULT_CATEGORY_1] = action_1 // 新增分类时直接在此添加对应动作即可 }; // 使用示例:通过分类间接执行动作 void handle_fault_by_category(FaultCode code) { if (code < FAULT_MAX) { FaultCategory cat = fault_to_category[code]; if (cat < FAULT_CATEGORY_MAX) { category_action_table[cat](); } } }
内容的提问来源于stack exchange,提问作者ro88
相关产品推荐
相关产品推荐

