Answers:
我知道这是原始查询之后的很长时间,但这可能仍然有用。
这可以在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(未加引号)无法与前面的字符串连接。
现在考虑预处理器字符串化(以前称为字符串化,文档中的链接已更改,以反映修订的术语。(顺便说一句,这两个术语都是可憎的。正确的术语当然是字符串化。准备更新)您的链接。))运算符。这仅对宏的参数起作用,并将未扩展的参数替换为双引号中的参数。从而:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
将为s1和s2分配相同的值。如果运行gcc -E,则可以在输出中看到它。也许将STR更好地命名为ENQUOTE。
这解决了将引号引起来的问题,现在的问题是,如果参数是宏,则宏将不会扩展。这就是为什么需要第二个宏的原因。XSTR扩展其参数,然后调用STR以将扩展的值放入引号中。
__IPHONE_9_3
。
BOOST_PP_STRINGIZE
对于C ++似乎是一个很好的解决方案,但对于常规C而言却不是。
这是我的GNU CPP解决方案:
/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))
上面的定义导致:
test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"
对于“定义为整数”,“定义为字符串”和“定义但没有值”变量,它们可以正常工作。仅对于“未定义”变量,它们显示的内容与原始变量名称完全相同。您必须习惯了-也许有人可以提供更好的解决方案。
DEFINED_INT=(sizeof(MY_STRUCT))
,而没有对sizeof
运算符进行评估。
sizeof
奇怪,因为它将进行评估的是编译器而不是预处理器,但是,仍然想知道是否有巧妙的方法来实现这一点。)
#define masks {0xff, 0xaf, 0x0f}
如果您使用的是Visual C ++,则可以使用#pragma message
:
#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))
编辑:感谢LB的链接
显然,GCC等效项(未经测试):
#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)
BOOST_PP_STRINGIZE
好且简短且可复制/粘贴,那将是很好的。
据我所知,'#error'仅会打印字符串,实际上您甚至不需要使用引号。
您是否尝试过使用“ BOOST_VERSION”编写各种故意不正确的代码?也许像“ blah [BOOST_VERSION] = foo;”之类的东西。会告诉您“字符串文字1.2.1不能用作数组地址”之类的内容。这不会是一个错误的消息,但至少它将向您显示相关值。您可以反复尝试,直到找到确实告诉您该值的编译错误为止。
std::vector<BOOST_VERSION>;
在gcc 4.4.1中。谢谢!
没有提升:
再次定义相同的宏,编译器HIMSELF将发出警告。
从警告中可以看到先前定义的位置。
先前定义的vi文件。
ambarish@axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition
#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666
int main ()
{
}
__cplusplus
。
在Microsoft C / C ++中,您可以使用内置函数_CRT_STRINGIZE()
来打印常量。我的许多stdafx.h
文件都包含以下内容的组合:
#pragma message("_MSC_VER is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION))
并输出如下内容:
_MSC_VER is 1915
_MFC_VER is 0x0E00
_ATL_VER is 0x0E00
WINVER is 0x0600
_WIN32_WINNT is 0x0600
_WIN32_IE is 0x0700
NTDDI_VERSION is 0x06000000
#define a <::BOOST_VERSION>
#include a
MSVC2015:致命错误C1083:无法打开包含文件:':: 106200':没有此类文件或目录
即使preprocess to file
已启用,即使存在无效令牌也可以使用:
#define a <::'*/`#>
#include a
MSVC2015:致命错误C1083:无法打开包含文件:'::'* /`#':没有这样的文件或目录
GCC4.x:警告:缺少终止'字符[-Winvalid-pp-token]#定义
<:: '* /`#>
Build error: #include expects "FILENAME" or <FILENAME>
。叹。
'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
你在找吗
#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif
如我所假设的,如果BOOST_VERSION是字符串,那不是很好,但是也可能为主,次和修订号定义了单个整数。
#if VARIABLE == 123
语句,语法高亮显示告诉我它是否是我认为的值……
您可以编写一个程序,将其打印出来BOOST_VERSION
并进行编译并作为构建系统的一部分运行。否则,我认为您不走运。
也请查看Boost文档,以了解如何使用宏:
参考BOOST_VERSION
,从http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros:
以XXYYZZ格式描述增强版本号,例如:
(BOOST_VERSION % 100)
是次要版本,次要版本和 主要版本。((BOOST_VERSION / 100) %
1000)
(BOOST_VERSION / 100000)