我想保存宏的原始文本值,以便我可以重新定义宏并仍然引用原始值。我的用例涉及宏的宏,所以我试图保存的值本身仍然是一个宏。我在网上翻译中尝试了一个小例子,我从这里复制代码。我知道其他SO问题讨论类似的想法,但我没有找到任何涵盖我的用例。
#include <stdio.h>
#define STR(X) (#X)
#define GLOBAL_INT (3)
// I AM TRYING TO SAVE THE TEXTUAL MACRO CONTENT "GLOBAL_INT" (WITHOUT THE QUOTES)
// IN ANOTHER MACRO SO THAT I CAN UNDEFINE GIM AND STILL REFER TO GLOBAL_INT
#define GIM (GLOBAL_INT)
#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);
#undef GIM
int main(int argc, char *argv[])
{
printf("strGimSave=%s\n", strGimSave);
printf("gimSaveStr=%s\n", gimSaveStr);
printf("strGimSaveM=%s\n", strGimSaveM);
printf("gimStr=%s\n", gimStr);
const char *gim_save = STR(GIM_SAVE);
const char *gim_save_str = GIM_SAVE_STR;
const char *str_gim_save = STR_GIM_SAVE;
printf("\ngim_save=%s\n", gim_save);
printf("gim_save_str=%s\n", gim_save_str);
printf("str_gim_save=%s\n", str_gim_save);
return 0;
}
Same code in online interpreter
编辑:我正在尝试输出&#34; GLOBAL_INT&#34;在上面的代码中。上面的代码输出:
strGimSave=GIM_SAVE
gimSaveStr=GIM
strGimSaveM=GIM_SAVE
gimStr=GIM
gim_save=GIM_SAVE
gim_save_str=GIM
str_gim_save=GIM_SAVE
答案 0 :(得分:3)
不可能。 C / C ++预处理器仅在评估时扩展宏。没有办法告诉它将宏定义为另一个的扩展结果。
那就是说,如果你使用STR的正确定义,你的样本的第一部分实际上会做你想要的:
#include <stdio.h>
// HERE, extra level of indirection
#define STR2(X) (#X)
#define STR(X) STR2(X)
#define GLOBAL_INT (3)
#define GIM (GLOBAL_INT)
#define GIM_SAVE (GIM)
#define GIM_SAVE_STR (STR(GIM))
#define STR_GIM_SAVE (STR(GIM_SAVE))
const char *strGimSave = STR(GIM_SAVE);
const char *gimSaveStr = GIM_SAVE_STR;
const char *strGimSaveM = STR_GIM_SAVE;
const char *gimStr = STR(GIM);
#undef GIM
int main(int argc, char *argv[])
{
printf("strGimSave=%s\n", strGimSave);
printf("gimSaveStr=%s\n", gimSaveStr);
printf("strGimSaveM=%s\n", strGimSaveM);
printf("gimStr=%s\n", gimStr);
const char *gim_save = STR(GIM_SAVE);
const char *gim_save_str = GIM_SAVE_STR;
const char *str_gim_save = STR_GIM_SAVE;
printf("\ngim_save=%s\n", gim_save);
printf("gim_save_str=%s\n", gim_save_str);
printf("str_gim_save=%s\n", str_gim_save);
return 0;
}
现在生成
strGimSave=(((3)))
gimSaveStr=((3))
strGimSaveM=(((3)))
gimStr=((3))
gim_save=(GIM)
gim_save_str=GIM
str_gim_save=(GIM)
正如您所看到的那样,#undef GIM
宏停止扩展到&#34; 3&#34;,但是在定义GIM时创建的字符串常量保留该值。使用您在这些宏中添加的所有括号。
答案 1 :(得分:2)
将预处理程序运算符应用于宏规范时,应该添加额外级别的间接(另一个宏),以便正确扩展宏规范。使用令牌连接运算符(##
)来考虑此示例:
#define TOKEN_CAT_IMPL(x,y) x##x
#define TOKEN_CAT(x,y) TOKEN_CAT_IMPL(x,y) // <--- Here x and y are expanded before passed
现在你可以随心所欲地使用它了:
#define FOO_IDENTIFIER( id ) TOKEN_CAT( foo_ , id );
#define ID hello
int FOO_IDENTIFIER( ID ) = 0; // int foo_hello = 0;
Here是一个正在运行的例子。
Here是您的代码,通过应用此处说明的解决方案。请注意第二个输出是GIM
,因为该宏未定义且GIM
仅被视为令牌。