C 防止间接级别内的宏扩展

C 防止间接级别内的宏扩展,c,concatenation,c-preprocessor,token,C,Concatenation,C Preprocessor,Token,下面是一个简单的程序,它接受宏测试,将_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; } 它工作得很好,但是如果我引入一个间接级别,预处理器现在使用TEST的值而不是token“TEST”,导致粘贴的token是0_

下面是一个简单的程序,它接受宏测试,将_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;
}
它工作得很好,但是如果我引入一个间接级别,预处理器现在使用TEST的值而不是token“TEST”,导致粘贴的token是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;
}
有没有办法让它像第一个示例一样工作(在扩展宏之前粘贴令牌),同时保持间接性?

您可以放弃使用“类似对象”的宏,并为
测试提供一个空参数列表

#define TEST() 0
现在,
TEST
将永远不会被替换,除非您主动将
()
放在它后面


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

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

    printf("%s\n", INDIRECTION(TEST,));

测试宏必须是未定义的,以避免在间接宏中展开

#define TEST 0
#define TEST_NAME "Joe"

#define ID_TO_NAME(id) id##_NAME

#ifdef TEST
#undef TEST

#define INDIRECTION(id) ID_TO_NAME(id)

#endif
int main(void) {
    printf("%s\n", ID_TO_NAME(TEST));
    printf("%s\n", INDIRECTION(TEST));
    return 0;
}

你能看到第二个参数是空的吗?@Meninx-メネンックス 是的,这就是重点。参数
\uu
是假的,因为它总是必须为空。@Meninx-メネンックス - 我能看到的是,尽管是间接的,程序还是会像OP一样打印“Joe”。@Meninx-メネンックス - 我关心OP是否能为他们不容易解决的问题找到可能的解决方案。@Meninx-メネンックス 我很乐意回答任何反对意见,但请描述您认为错误的地方和原因,而不是重复您不喜欢它。既然OP已经在问题中写到了这一点,想必这不是一个可行的解决方案。关键的部分是,
如果我引入一个间接层次的话
。几年前我遇到了这个问题。我甚至为此起草了一个问题。然而,我的结论是,在我的职权范围内,这不是标准C所能做到的事情——因此,这个问题没有被问到,就消失了。我很确定这同样适用于您,假设您需要在使用
间接
宏时定义的
测试
宏,并且您无法建立有关
测试
的可能值的知识(因此,在使用
间接
然后恢复之前的
测试定义
时,没有一种明智的方法来
取消测试
)。