如何评估嵌套的预处理器宏(How to evaluate a nested preprocessor macro)

比方说,我想选择某个预处理器指令的行为,在编译时评估一个常量字符串和另一个宏的结果的连接。

#define CASE1 text1 #define CASE2 text2 #define CASE3 text3 #define SCENARIO 3 /** the following won't work - for examplification purposes only**/ #define FUNCTION CASE##SCENARIO /** whenever I write FUNCTION, I expect to see text3 **/

我很难想到一个可行的解决方案,因为预处理器是一次通过的野兽。 这甚至可行吗?

let's say I want to select the behaviour of a certain preprocessor directive evaluating at compile time the concatenation of a constant string and the result of another macro.

#define CASE1 text1 #define CASE2 text2 #define CASE3 text3 #define SCENARIO 3 /** the following won't work - for examplification purposes only**/ #define FUNCTION CASE##SCENARIO /** whenever I write FUNCTION, I expect to see text3 **/

I am having an hard time thinking of a viable solution, as the preprocessor is a one-pass beast. Is that even feasible ?

最满意答案

这是可能的,你只需要添加一些额外的宏层。 关键是当你使用令牌粘贴操作符## ,预处理器不会扩展其操作数。 但是,如果添加另一层宏,预处理器将展开这些参数。 例如:

#define CASE1 text1 #define CASE2 text2 #define CASE3 text3 #define SCENARIO 3 #define TOKENPASTE_HELPER(x, y) x ## y #define TOKENPASTE(x, y) TOKENPASTE_HELPER(x, y) #define FUNCTION TOKENPASTE(CASE, SCENARIO)

当预处理器扩展FUNCTION ,它将扩展TOKENPASTE 。 当它扩展TOKENPASTE ,它扩展了它的arugments(因此SCENARIO被3替换),因为它的参数都不是令牌粘贴操作符的操作数。 接下来,它展开TOKENPASTE_HELPER ,它执行实际的令牌粘贴来制作CASE3 。 最后,它扩展了CASE3宏以获取text3 。

It's possible, you just need to add some extra layers of macros. The key is that when you use the token-pasting operator ##, the preprocessor will not expand its operands. But, if you add another layer of macros, the preprocessor will expand those arguments. For example:

#define CASE1 text1 #define CASE2 text2 #define CASE3 text3 #define SCENARIO 3 #define TOKENPASTE_HELPER(x, y) x ## y #define TOKENPASTE(x, y) TOKENPASTE_HELPER(x, y) #define FUNCTION TOKENPASTE(CASE, SCENARIO)

When the preprocessor expands FUNCTION, it expands TOKENPASTE. When it expands TOKENPASTE, it expands its arugments (so SCENARIO gets replaced by 3), since neither of its arguments are operands of the token-pasting operator. Next, it expands TOKENPASTE_HELPER, which does the actual token pasting to make CASE3. Finally, it expands the CASE3 macro to get text3.

更多推荐