防止间接级别内的宏扩展

use*_*047 8 c concatenation token c-preprocessor

以下是一个简单的程序,它采用宏 TEST,将 _NAME 粘贴到标记的末尾,然后打印结果。

#define TEST 0
#define TEST_NAME "Joe"

#define ID_TO_NAME(id) id ## _NAME

int main(void) {
    printf("%s\n", ID_TO_NAME(TEST));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但是如果我引入一定程度的间接,预处理器现在使用 TEST 的值而不是标记“TEST”,导致粘贴的标记为 0_NAME 而不是 TEST_NAME。

#define TEST 0
#define TEST_NAME "Joe"

#define ID_TO_NAME(id) id ## _NAME

#define INDIRECTION(id) ID_TO_NAME(id)

int main(void) {
    printf("%s\n", INDIRECTION(TEST));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以让它像第一个示例一样运行(在扩展宏之前粘贴令牌),同时保持间接性?

Pot*_*ter 6

您可以放弃使用“类似对象”宏并给出TEST一个空参数列表。

#define TEST() 0
Run Code Online (Sandbox Code Playgroud)

现在TEST永远不会被取代,除非你积极地追求()它。


您可以##向每个传递令牌的宏添加一个虚假运算符,而不扩展它。然而,这也需要一个伪造的参数。

#define INDIRECTION(id,_) ID_TO_NAME(id##_)

    printf("%s\n", INDIRECTION(TEST,));
Run Code Online (Sandbox Code Playgroud)

  • @Meninx-meninkkusu 我很乐意解决任何异议,但请描述您认为错误的内容以及原因,而不是重复您不喜欢它。由于OP已经在问题中写到了这一点,想必这不是一个可行的解决方案。关键部分是“如果我引入一定程度的间接性”。 (3认同)