macros - 如何在编译时显示 #define 的值?

标签 macros c-preprocessor boost-preprocessor

我试图找出我的代码认为它使用的 Boost 版本。我想做这样的事情:

#error BOOST_VERSION

但预处理器不会扩展 BOOST_VERSION。

我知道我可以在程序运行时将其打印出来,并且我知道我可以查看预处理器的输出来找到答案。我觉得在编译过程中找到一种方法可能会很有用。

最佳答案

我知道这距离原始查询已经过去很长时间了,但这可能仍然有用。

这可以在 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,文档中的链接已更改以反射(reflect)修订后的术语。(顺便说一句,这两个术语同样令人讨厌。当然,正确的术语是 stringifaction。Be准备更新您的链接。))运营商。这只作用于宏的参数,并将未展开的参数替换为用双引号括起来的参数。因此:

#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);

将为 s1 和 s2 分配相同的值。如果运行 gcc -E 您可以在输出中看到这一点。也许将 STR 命名为 ENQUOTE 之类的名称会更好。

这解决了在未加引号的项目周围加上引号的问题,现在的问题是,如果参数是宏,则宏将不会被扩展。这就是需要第二个宏的原因。 XSTR 扩展其参数,然后调用 STR 将扩展的值放入引号中。

关于macros - 如何在编译时显示 #define 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1562074/

相关文章:

Emacs:有没有办法使用 Emacs 创建交互式脚本?

c++ - C 和 C++ 构建过程的区别

c++ - #define 可以被赋予定义的结果吗?

c - 如何使用预处理器缩短这些行?

c++ - Boost 是否使用合法的 C++ 预处理指令语法?

c++ - 如何使用 boost 预处理器生成访问器?

c++ - 如何在多个平台上使用__FILE__和__LINE__ info实现C/C++可变参数记录宏?

c++ - 使用 VS 宏设置 PreprocessorDefinitions

c - C include guards到底做了什么?

可变序列 : How to create similar code block for each argument/type? 的 C++ 模板和代码生成