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

查看:249
本文介绍了如何在编译时显示#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中使用字符串化运算符#"来完成,但是它需要两个阶段.

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

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

宏的值随后可以显示为:

The value of a macro can then be displayed with:

#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.

现在考虑预处理器字符串化(以前称为字符串化,但文档中的链接已更改,以反映修订的术语.(顺便提一下,这两个术语都是可憎的.正确的术语当然是stringifaction.准备更新您的链接.))运算符.这仅对宏的参数起作用,并将未扩展的参数替换为双引号中的参数.因此:

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天全站免登陆