预处理器宏 C/Objective-C

Preprocessor macro C/Objective-C

你好,我正在尝试制作一个获取参数并尝试向其添加 postFix 的宏。

#define myPostFix HelloWorld
#define macro(x) x ##myPostFix 
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)

预期行为是获取

CAlgThreadHandleObjectHelloWorld

我实际得到的是:

CAlgThreadHandleObjectmyPostFix 

Some1 可以帮助我获得预期的行为吗? 请注意 myPostFix 是我必须在项目 GCC 定义中定义的东西,它应该因项目而异。

尝试:

#define myPostFix HelloWorld
#define macro_2(x, y) x##y
#define macro_1(x, y) macro_2(x, y)
#define macro(x) macro_1(x, myPostFix)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject)

您需要中间 macro_1 来让预处理器替换 myPostFix 赋值,然后 macro_2 来连接字符串。 此解决方案可让您将 myPostFix 分配给您想要的值。

为了阐明预处理器和符号替换的工作原理,考虑到预处理翻译阶段在参数上不是递归的,因此翻译需要通过 forced 参数扩展不止一次最多展开所有参数。
在我们的例子中:

  1. CAlgThreadHandleObject 扩展为:macro(CAlgThreadHandleObject)
  2. macro(CAlgThreadHandleObject) 扩展为:macro_1(CAlgThreadHandleObject, myPostFix)
  3. macro_1 扩展为:macro_2(CAlgThreadHandleObject, HelloWorld)
  4. 最后 macro_2 扩展为:CAlgThreadHandleObjectHelloWorld

你实际上需要深入三层才能使宏正确展开。我无法假装理解为什么这是必要的确切原因(不是我想理解...)

#define MY_ADDPOSTFIX3(x, y) x ## y
#define MY_ADDPOSTFIX2(x, y) MY_ADDPOSTFIX3(x, y)
#define MY_ADDPOSTFIX(x) MY_ADDPOSTFIX2(x, MY_POSTFIX)

MY_ADDPOSTFIX(Func)

你可以测试这个:

$ gcc -E test.c -DMY_POSTFIX=HelloWorld
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"




FuncHelloWorld

还有...

$ gcc -E test.c -DMY_POSTFIX=Goodbye | tail -n 1
FuncGoodbye

只需通过另一个宏调用传递它 macro,这样定义就会扩展。我稍微改变了宏,但功能是一样的:

#define myPostFix HelloWorld
#define macro2(x,y) x##y
#define macro(x,y) macro2(x,y)
#define CAlgThreadHandleObject macro(CAlgThreadHandleObject,myPostFix)