如何正确定义名称由其他宏拼接的宏?解决##连接符使用问题
解决宏拼接后的条件定义问题
问题核心是:预处理器在#ifndef和#define这类条件编译指令中,不会自动展开宏调用,所以直接写UART_PIN_TX_PORT(PORT_NUMBER)无法正确解析为拼接后的目标宏名(比如UART_PIN_TX_PORT3)。需要添加一层辅助宏来完成完全展开。
正确的实现代码如下:
#ifndef PORT_NUMBER // 可在编译时定义该宏 #define PORT_NUMBER 3 #endif // 第一层:触发参数展开 #define UART_PIN_TX_PORT(x) UART_PIN_TX_PORT_(x) // 第二层:完成字符串拼接 #define UART_PIN_TX_PORT_(x) UART_PIN_TX_PORT ## x // 新增辅助宏,用于在条件编译中完成宏展开 #define DEFINE_IF_NOT_EXISTS(NAME, VALUE) \ #ifndef NAME \ #define NAME VALUE \ #endif // 调用辅助宏,先展开得到目标宏名,再进行条件定义 DEFINE_IF_NOT_EXISTS(UART_PIN_TX_PORT(PORT_NUMBER), -1)
原理说明
UART_PIN_TX_PORT(PORT_NUMBER)会先被展开为UART_PIN_TX_PORT3(通过两层宏的展开+拼接)。- 辅助宏
DEFINE_IF_NOT_EXISTS接收展开后的宏名和值,在内部完成#ifndef和#define的逻辑,这样预处理器就能正确识别拼接后的宏名,判断是否已定义,未定义则赋值为-1。
如果不需要通用的辅助宏,也可以用更直接的方式实现:
#ifndef PORT_NUMBER #define PORT_NUMBER 3 #endif #define UART_PIN_TX_PORT(x) UART_PIN_TX_PORT_(x) #define UART_PIN_TX_PORT_(x) UART_PIN_TX_PORT ## x // 先手动展开宏名,再进行条件定义 #define TARGET_MACRO UART_PIN_TX_PORT(PORT_NUMBER) #ifndef TARGET_MACRO #define TARGET_MACRO -1 #endif // 如需保留原宏调用形式,可额外定义(可选) #define UART_PIN_TX_PORT(PORT_NUMBER) TARGET_MACRO
内容的提问来源于stack exchange,提问作者ONLYA
相关产品推荐
相关产品推荐

