【发布时间】:2018-05-30 01:56:09
【问题描述】:
这是this one 的后续问题(也更接近手头的实际问题)。
如果我有以下情况:
#include <stdio.h>
#define FOO_ONE 12
#define FOO_TWO 34
#define BAR_ONE 56
#define BAR_TWO 78
#define FOO 99
#define STRINGIFY(mac) #mac
#define CONCAT(mac1, mac2) STRINGIFY(mac1) STRINGIFY(mac2)
#define MAKE_MAC(mac) CONCAT(mac##_ONE, mac##_TWO)
#define PRINT(mac) printf(#mac ": " MAKE_MAC(mac) "\n")
void main(int argc, char *argv[])
{
PRINT(FOO);
PRINT(BAR);
}
可以看出,字符串化的连接宏随后被替换在 printf() 语句中,该语句本身位于宏中。
因为FOO被定义(如99),它恰好在与_ONE和_TWO连接之前被扩展,有效地创建了标记99_ONE和99_TWO。
这个程序输出:
FOO: 99_ONE99_TWO
BAR: 5678
如何推迟 FOO 宏的扩展(实际上,完全消除它,以获得所需的输出:
FOO: 1234
BAR: 5678
注意:假设PRINT() 宏签名无法更改(即无法添加参数等)。然而,它的实现可以改变。此外,FOO、FOO_* 和 BAR_* 定义也不能修改。
【问题讨论】:
-
由于
FOO、FOO_*和BAR_*都不能被修改,如何防止PRINT(FOO)中发生从FOO到99的替换? -
@Stan - 确实是个问题......这就是为什么我正在寻找 SE 大师来寻找创意...... 8-)
-
@Stan - 我希望对底层宏级联进行重新排序可以解决问题,但您强调问题的根源在于 API 宏本身。
-
确实,在这种情况下放弃宏观想法会更优雅。这种实现的最初需求是什么?
FOO,BAR不能是数组吗?正如您在另一条评论中提到的,有数百个宏,为了增加灵活性,我们还可以考虑将所有宏封装成“实际”变量和函数。
标签: c macros c-preprocessor evaluation