防止间接级别内的宏扩展

时间:2017-01-19 05:23:48

标签: c concatenation c-preprocessor token

以下是一个简单的程序,它接受宏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;
}

它运行正常,但是如果我引入一个间接级别,预处理器现在使用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;
}

有没有办法让它像第一个例子一样(在扩展宏之前粘贴令牌)同时保持间接?

2 个答案:

答案 0 :(得分:1)

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

#define TEST() 0

现在TEST永远不会被替换,除非您主动将()放在其后面。

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

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

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

答案 1 :(得分:0)

必须未定义TEST宏,以避免在INDIRECTION宏中扩展

#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;
}