预处理器宏 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 参数扩展不止一次最多展开所有参数。
在我们的例子中:
CAlgThreadHandleObject
扩展为:macro(CAlgThreadHandleObject)
macro(CAlgThreadHandleObject)
扩展为:macro_1(CAlgThreadHandleObject, myPostFix)
macro_1
扩展为:macro_2(CAlgThreadHandleObject, HelloWorld)
- 最后
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)
你好,我正在尝试制作一个获取参数并尝试向其添加 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 参数扩展不止一次最多展开所有参数。
在我们的例子中:
CAlgThreadHandleObject
扩展为:macro(CAlgThreadHandleObject)macro(CAlgThreadHandleObject)
扩展为:macro_1(CAlgThreadHandleObject, myPostFix)
macro_1
扩展为:macro_2(CAlgThreadHandleObject, HelloWorld)
- 最后
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)