gpt4 book ai didi

c - 在生成器宏中删除参数

转载 作者:太空狗 更新时间:2023-10-29 17:24:49 26 4
gpt4 key购买 nike

我目前正在开发一个包含大量枚举的代码库。需要将 enum 值与字符串表示形式相互转换。为此,有一堆辅助宏可以对表单上的宏进行操作

#define THINGS_MAP(G, P) \
G(LAMP, P) \
G(DESK, P)

在代码的其他地方,有一些宏的工作原理大致如下:

#define MK_ENUM(SYM, P) P##_##SYM,
enum { THINGS_MAP(MK_ENUM, THING) }; /* expands to { THING_LAMP, THING_DESK, } */

我想避免在枚举中更改 MK_ENUM 和调用 THINGS_MAP

但是,我现在有一个特别长的enum 列表,我还需要为其中的条目添加一些分类。所以我在考虑做类似的事情

#define THINGS_PROP_MAP(G, P) \
G(LAMP, WOODEN, P) \
G(DESK, METALIC, P)

但是,由于我所有的辅助宏都需要传递两个参数,而不是三个,所以我在考虑是否可以映射某种删除参数的宏。这可能吗?

我正在寻找的是:

#define THINGS_PROP_MAP(G, P) \
G(LAMP, WOODEN, P) \
G(DESK, METALIC, P)

/* DROP_PROP should create G(LAMP, P) G(DESK, P) */
#define THINGS_MAP(G, P) DROP_PROP(THINGS_PROP_MAP)

我有一个想法是添加一个额外的转换步骤,但我没有让它工作

#define THINGS_PROP_MAP(G, T, P) \
G(T(LAMP, WOODEN, P)) \
G(T(DESK, METALIC, P))
#define DROP_PROP(SYM, _ , P) SYM, P
#define THING_MAP(G, P) THING_PROP_MAP(G, DROP_PROP, P)

是的,我知道这远远超出了宏滥用等 :-)

最佳答案

您的宏没问题,但您的#define MK_ENUM(SYM, P) P##_##SYM, 需要两个参数,其中此调用 G(T(LAMP, WOODEN, P )) 例如 G = MK_ENUM 仅使用一个参数调用 G,即使内部语句将扩展为 LAMP, P .

要强制预处理器执行一个额外的扩展步骤并识别 LAMP, P 不是您必须添加的单个标记:

#define MK_ENUM_EXPAND(...) MK_ENUM(__VA_ARGS__)

然后使用:

enum { THING_MAP(MK_ENUM_EXPAND, THING) };

进一步注意,您的宏不会展开为 enum { THING_LAMP, THING_DESK };,而是在末尾有一个逗号 enum { THING_LAMP, THING_DESK, }; .

完整的工作代码:

#define MK_ENUM(SYM, P) P##_##SYM,
#define MK_ENUM_EXPAND(...) MK_ENUM(__VA_ARGS__)

#define THINGS_PROP_MAP(G, T, P) \
G(T(LAMP, WOODEN, P)) \
G(T(DESK, METALIC, P))

#define DROP_PROP(SYM, _ , P) SYM, P

#define THINGS_MAP(G, P) THINGS_PROP_MAP(G, DROP_PROP, P)

enum { THINGS_MAP(MK_ENUM_EXPAND, THING) }; /* expands to { THING_LAMP, THING_DESK, } */

要测试宏扩展,将 gcc 与命令行参数 -E 一起使用是很有用的:

$ gcc -E srcFile.c

因为您收到了具体的错误消息并了解出了什么问题。


如果您不想在枚举中更改 MK_ENUM 和对 THINGS_MAP 的调用,您可以执行以下操作,我只是连接 G##STHINGS_PROP_MAP 中,其中 G = MK_ENUMS = _EXPAND:

#define MK_ENUM(SYM, P) P##_##SYM,
#define MK_ENUM_EXPAND(...) MK_ENUM(__VA_ARGS__)

#define THINGS_PROP_MAP(G, S, T, P) \
G##S(T(LAMP, WOODEN, P)) \
G##S(T(DESK, METALIC, P))

#define DROP_PROP(SYM, _ , P) SYM, P

#define THINGS_MAP(G, P) THINGS_PROP_MAP(G, _EXPAND, DROP_PROP, P)

enum { THINGS_MAP(MK_ENUM, THING) }; /* expands to { THING_LAMP, THING_DESK, } */

关于c - 在生成器宏中删除参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45028108/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com