我可以使用标记粘贴来处理编译时命名吗?

标签 c c-preprocessor

假设我有一个文件,我可以#include定义如下内容:

#define GROUP_NUMBER_FOO 42
#define GROUP_NUMBER_BAR 37

我想#define一个宏,如果像这样调用

GROUPID(FOO)(x);
GROUPID(BAR)(x);

转换为

GROUP42_ELEMENT_FOO(x);
GROUP37_ELEMENT_BAR(x);

我希望这可以通过标记粘贴来完成(如 Nested ## operator in C PreprocessorHow to concatenate twice with the C preprocessor and expand a macro as in "arg ## _ ## MACRO"? ),但我似乎不知道如何做到这一点。

类似

#define EXTRACT_GROUP(name) GROUP_NUMBER_##name
#define GROUPID(name) GROUP##EXTRACT_GROUP(name)##_ELEMENT_##name

但是如果我尝试使用GROUPID(FOO),则会收到错误:

 error: pasting ")" and "_ELEMENT_" does not give a valid preprocessing token

(在有人说“XY 问题!”之前,我正在尝试以更明智的方式适应一些现有的尴尬 API。)

最佳答案

啊哈,我跌跌撞撞地穿过了它;看来我需要添加额外的间接级别:

#define GROUP_NUMBER_FOO 42
#define GROUP_NUMBER_BAR 37

#define CONCAT(x,y) x##y
#define EVALCAT(x,y) CONCAT(x,y)
#define CONCAT4(x,y,z,w) x##y##z##w
#define EVALCAT4(x,y,z,w) CONCAT4(x,y,z,w)
#define EXTRACT_GROUP(name) CONCAT(GROUP_NUMBER_,name)
#define GROUPID(name) EVALCAT4(GROUP,EXTRACT_GROUP(name),_ELEMENT_,name)

GROUPID(FOO)
GROUPID(BAR)

将其转换为所需的内容

GROUP42_ELEMENT_FOO
GROUP37_ELEMENT_BAR

关于我可以使用标记粘贴来处理编译时命名吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58987555/

相关文章:

c - 信号量不会让进程休眠

c++ - 生成的静态数组的包装器宏

c - 二分查找算法的平均性能?

c - 为什么这些代码给我一个 sigsegv 错误?

c++ - "define"函数返回类型前

c - 如何将某些内容附加到逗号分隔列表(作为宏实现)并使用 C 预处理器将其转换为字符串?

c++ - 在编译期间操作字符串的 C/C++ 宏

c - 如果 c 不支持运算符重载,我们如何在#include 指令中使用小于号( '<' 或什至大于( '>'))?

c - Qsort 不排序 char * 数组

c - 如何解析同名的 C++ 成员函数与 C 函数?