我知道这是在原始查询之后很长时间,但这可能仍然有用。
这可以在 GCC 中使用 stringify 运算符“#”来完成,但它需要两个阶段。
#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(未加引号)不能与前面的字符串连接。
现在考虑预处理器字符串化(它曾经被称为字符串化,文档中的链接已更改以反映修订后的术语。(顺便说一句,这两个术语同样令人讨厌。正确的术语当然是字符串化。是准备更新您的链接。))运营商。这仅对宏的参数起作用,并将未扩展的参数替换为用双引号括起来的参数。因此:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
将为 s1 和 s2 分配相同的值。如果你运行 gcc -E 你可以在输出中看到这个。或许 STR 更适合命名为 ENQUOTE。
这解决了在未引用的项目周围加上引号的问题,现在的问题是,如果参数是宏,宏将不会被扩展。这就是需要第二个宏的原因。 XSTR 扩展其参数,然后调用 STR 将扩展后的值放入引号中。