保存c++预处理器宏的原始值
Save original value of C++ preprocessor macro
我想保存宏的原始文本值,以便我可以在重新定义宏时仍然引用原始值。我的用例涉及一个宏到一个宏,所以我试图保存的值本身仍然是一个宏。我有一个在线解释器尝试的小例子,我从这里复制代码。我知道其他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=%sn", strGimSave);
printf("gimSaveStr=%sn", gimSaveStr);
printf("strGimSaveM=%sn", strGimSaveM);
printf("gimStr=%sn", 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=%sn", gim_save);
printf("gim_save_str=%sn", gim_save_str);
printf("str_gim_save=%sn", str_gim_save);
return 0;
}
在线解释器中的相同代码
编辑:我正试图在上述代码中输出"GLOBAL_INT"。以上代码输出:
strGimSave=GIM_SAVE
gimSaveStr=GIM
strGimSaveM=GIM_SAVE
gimStr=GIM
gim_save=GIM_SAVE
gim_save_str=GIM
str_gim_save=GIM_SAVE
不可能。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=%sn", strGimSave);
printf("gimSaveStr=%sn", gimSaveStr);
printf("strGimSaveM=%sn", strGimSaveM);
printf("gimStr=%sn", 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=%sn", gim_save);
printf("gim_save_str=%sn", gim_save_str);
printf("str_gim_save=%sn", str_gim_save);
return 0;
}
现在生产
strGimSave=(((3)))
gimSaveStr=((3))
strGimSaveM=(((3)))
gimStr=((3))
gim_save=(GIM)
gim_save_str=GIM
str_gim_save=(GIM)
(参见live on coliru)
正如您所看到的,一旦您执行了#undef GIM
,宏就不再扩展为"3",但是在定义GIM时创建的字符串常量保留了该值。这些宏中都有括号
当对宏参数应用预处理器操作符时,您应该添加额外的间接层(另一个宏),以适当地展开宏参数。考虑这个使用令牌连接操作符(##
)的示例:
#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;
下面是一个正在运行的例子。
编辑:下面是通过应用这里解释的解决方案来工作的代码。请注意第二个输出是GIM
,因为该宏是未定义的,并且GIM
仅被视为标记。
相关文章:
- #定义c-预处理器常量..我做错了什么
- 预处理器:插入结构名称中的前一个行号
- 如何在c++中实现处理器调度模拟器
- C/C++预处理器是否可以检测一些编译器选项
- 将浮动的heightmap数组导出为16位原始值
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 在clang++预处理器中确定gcc工具链版本
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 不同/较旧的处理器运行c++代码的方式是否不同
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 用于交叉编译和CMake的预处理器宏的单元测试
- 有没有办法在从编译器获取参数时避免预处理器宏?
- 如何比较两个同名的预处理器宏?
- 如何将原始字节附加到 std::vector?
- 从堆栈分配的原始指针构造智能指针
- 从预处理器获取 Windows 版本(C++ Win32)
- 有没有一种方法可以使用预处理器将文本资源拉入原始字符串
- 作为预处理器宏参数的多行原始字符串文字
- 保存c++预处理器宏的原始值