我知道这距离原始查询已经过去很长时间了,但这可能仍然有用。
这可以在 GCC 中使用字符串化运算符“#”来完成,但需要首先定义两个附加阶段。
#define XSTR(x) STR(x)
#define STR(x) #x
然后可以通过以下方式显示宏的值:
#pragma message "The value of ABC: " XSTR(ABC)
请参阅:gcc 在线文档中的 3.4 字符串化。
怎么运行的:
预处理器理解带引号的字符串,并以不同于普通文本的方式处理它们。字符串连接是这种特殊处理的一个例子。消息杂注需要一个带引号的字符串参数。当参数有多个组件时,它们必须都是字符串,以便可以应用字符串连接。预处理器永远不能假设应将未加引号的字符串视为已加引号的字符串。如果是的话:
#define ABC 123
int n = ABC;
不会编译。
现在考虑:
#define ABC abc
#pragma message "The value of ABC is: " ABC
这相当于
#pragma message "The value of ABC is: " abc
这会导致预处理器警告,因为 abc(不带引号)无法与前面的字符串连接。
现在考虑预处理器 stringize (曾经称为 stringification,文档中的链接已更改以反映修订后的术语。(顺便说一句,这两个术语同样令人讨厌。当然,正确的术语是 stringifaction。准备好更新您的链接。))运营商。这只作用于宏的参数,并将未扩展的参数替换为用双引号括起来的参数。因此:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
将为 s1 和 s2 分配相同的值。如果运行 gcc -E 您可以在输出中看到这一点。也许 STR 更适合命名为 ENQUOTE 之类的名称。
这解决了在未加引号的项目周围加上引号的问题,现在的问题是,如果参数是宏,则宏将不会被扩展。这就是需要第二个宏的原因。 XSTR 扩展其参数,然后调用 STR 将扩展的值放入引号中。