编译期如何检查带括号与类型转换的C宏的值?
解决预处理器无法识别带类型转换宏的编译检查问题
当需要检查带类型强制转换的#define宏数值是否符合要求,但预处理器不识别typedef对应的类型导致直接比较报错时,可以通过定义辅助宏剥离类型转换和外层括号,提取原始数值后再进行预编译检查,且无需修改原宏和typedef。
核心辅助宏定义
// 剥离宏最外层的括号 #define REMOVE_OUTER_PARENS(x) _REMOVE_OUTER_PARENS x #define _REMOVE_OUTER_PARENS(...) __VA_ARGS__ // 剥离类型转换部分,提取原始数值 #define EXTRACT_FROM_CAST(x) _EXTRACT_FROM_CAST x #define _EXTRACT_FROM_CAST(type, val) val
针对configTICK_RATE_HZ的实现
假设原宏为#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ),定义组合宏提取数值后进行检查:
#define GET_TICK_RATE_VALUE EXTRACT_FROM_CAST(REMOVE_OUTER_PARENS(configTICK_RATE_HZ)) // 预编译检查,不符合则终止编译 #if (1000 != GET_TICK_RATE_VALUE) #error "configTICK_RATE_HZ must be 1000" #endif
测试代码验证(针对你提供的FREQ_HZ示例)
修改后的完整测试代码:
#include <stdio.h> #define FREQ_HZ ((int)10) // 不可修改该定义 // 辅助宏 #define REMOVE_OUTER_PARENS(x) _REMOVE_OUTER_PARENS x #define _REMOVE_OUTER_PARENS(...) __VA_ARGS__ #define EXTRACT_FROM_CAST(x) _EXTRACT_FROM_CAST x #define _EXTRACT_FROM_CAST(type, val) val #define GET_FREQ_VALUE EXTRACT_FROM_CAST(REMOVE_OUTER_PARENS(FREQ_HZ)) #if (10 != GET_FREQ_VALUE) #error "Bad frequency value" #endif int main(void) { printf("Hello world\n"); }
原理说明
REMOVE_OUTER_PARENS(configTICK_RATE_HZ)会将((TickType_t)1000)展开为(TickType_t)1000,剥离最外层括号;EXTRACT_FROM_CAST接收剥离后的(TickType_t)1000,将其拆分为type(即TickType_t)和val(即1000),最终返回数值部分;- 预处理器展开
GET_TICK_RATE_VALUE后得到纯数值,此时#if比较不会再因类型转换报错。
内容的提问来源于stack exchange,提问作者AamerAirlines
相关产品推荐
相关产品推荐

