如何在编译时显示 #define 的值? [英] How do I show the value of a #define at compile-time?

查看:51
本文介绍了如何在编译时显示 #define 的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚我的代码认为它正在使用哪个版本的 Boost.我想做这样的事情:

I am trying to figure out what version of Boost my code thinks it's using. I want to do something like this:

#error BOOST_VERSION

但预处理器不会扩展 BOOST_VERSION.

but the preprocessor does not expand BOOST_VERSION.

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

I know I could print it out at run-time from the program, and I know I could look at the output of the preprocessor to find the answer. I feel like having a way of doing this during compilation could be useful.

推荐答案

我知道这是在原始查询之后的很长一段时间,但这可能仍然有用.

I know that this is a long time after the original query, but this may still be useful.

这可以在 GCC 中使用 stringify 运算符#"来完成,但它需要两个阶段.

This can be done in GCC using the stringify operator "#", but it requires two stages.

#define XSTR(x) STR(x)
#define STR(x) #x

然后可以显示宏的值:

#pragma message "The value of ABC: " XSTR(ABC)

参见:gcc 在线文档中的 3.4 字符串化.

See: 3.4 Stringification in the gcc online documentation.

它是如何工作的:

预处理器理解带引号的字符串并以不同于普通文本的方式处理它们.字符串连接就是这种特殊处理的一个例子.消息杂注需要一个带引号的字符串的参数.当参数有多个组件时,它们必须都是字符串,以便可以应用字符串连接.预处理器永远不能假设一个未引用的字符串应该被视为被引用.如果是的话:

The preprocessor understands quoted strings and handles them differently from normal text. String concatenation is an example of this special treatment. The message pragma requires an argument that is a quoted string. When there is more than one component to the argument then they must all be strings so that string concatenation can be applied. The preprocessor can never assume that an unquoted string should be treated as if it were quoted. If it did then:

#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(未加引号)不能与前面的字符串连接.

This causes a preprocessor warning because abc (unquoted) cannot be concatenated with the preceding string.

现在考虑预处理器字符串化(它曾经被称为字符串化,文档中的链接已更改以反映修订后的术语.(顺便说一句,这两个术语同样令人讨厌.正确的术语当然是字符串化.是准备更新您的链接.))运营商.这仅作用于宏的参数,并用双引号括起来的参数替换未扩展的参数.因此:

Now consider the preprocessor stringize (Which was once called stringification, the links in the documentation have been changed to reflect the revised terminology. (Both terms, incidentally, are equally detestable. The correct term is, of course, stringifaction. Be ready to update your links.)) operator. This acts only on the arguments of a macro and replaces the unexpanded argument with the argument enclosed in double quotes. Thus:

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

将为 s1 和 s2 分配相同的值.如果你运行 gcc -E 你可以在输出中看到这个.或许 STR 更适合命名为 ENQUOTE.

will assign identical values to s1 and s2. If you run gcc -E you can see this in the output. Perhaps STR would be better named something like ENQUOTE.

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

This solves the problem of putting quotes around an unquoted item, the problem now is that, if the argument is a macro, the macro will not be expanded. This is why the second macro is needed. XSTR expands its argument, then calls STR to put the expanded value into quotes.

这篇关于如何在编译时显示 #define 的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆