【发布时间】:2015-03-13 14:10:32
【问题描述】:
我有一组目标宏,我想根据选择的宏为其生成别名,如下所示:
选择宏:
#define I2C_MODULE 1
别名宏(概念形式):
#define I2C_MODULE_BASE I2C<Value of I2C_MODULE>_BASE
#define I2C_MODULE_NVIC INT_I2C<Value of I2C_MODULE>
目标宏(来自我无法控制的外部文件):
#define INT_I2C0 24
#define INT_I2C1 53
...
#define I2C0_BASE 0x40020000
#define I2C1_BASE 0x40021000
...
我想让预处理器生成别名宏 I2C_MODULE_BASE 和 I2C_MODULE_NVIC
选择宏 I2C_MODULE,但在大量阅读 Q1、P1 和许多其他我忘记的参考资料之后,我最终硬编码了它们的值。下面我展示了我当前的工作定义,然后是我最后一次失败的生成宏的尝试:
什么有效:
#define I2C_MODULE 1
#define I2C_MODULE_BASE I2C1_BASE
#define I2C_MODULE_NVIC INT_I2C1
什么不起作用:
#define I2C_MODULE 1
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
/* Attempt 1 */
#define I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)
/* Attempt 2 */
#define _I2C_MODULE_BASE "I2C" STR(I2C_MODULE) "_BASE"
#define _I2C_MODULE_NVIC "INT_I2C" STR(I2C_MODULE)
#define I2C_MODULE_BASE _I2C_MODULE_BASE
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC
编辑:我扩展了accepted answer 以到达我想要的位置,如下所示:
#define PASTE2(a, b) a ## b
#define PASTE3(a, b, c) a ## b ## c
#define _I2C_MODULE_BASE(x) PASTE3(I2C, x, _BASE)
#define _I2C_MODULE_NVIC(x) PASTE2(INT_I2C, x)
#define I2C_MODULE_BASE _I2C_MODULE_BASE(I2C_MODULE)
#define I2C_MODULE_NVIC _I2C_MODULE_NVIC(I2C_MODULE)
【问题讨论】:
-
您需要什么?宏还是字符串?
-
我不明白,你为什么要处理字符串?普通的旧
##标识符连接在这里应该可以正常工作,但诚然,如果您开始嵌套这些构造,您可能会遇到评估顺序问题 -
看看C preprocessor and token concatenation——它应该能解决你的问题。
-
注:以下划线开头的名称保留用于“实现”(有关详细信息,请参阅 ISO/IEC 9899:2011 §7.1.3 保留标识符)。最好避免自己定义此类名称 - 尽管您经常(甚至通常)会侥幸成功,直到您迁移到新的操作系统或类似的东西。
标签: c concatenation c-preprocessor stringification