How do I show the value of a #define at compile-time?

☆樱花仙子☆ 提交于 2019-11-28 02:56:23

If you are using Visual C++, you can use #pragma message:

#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))

Edit: Thanks to LB for link

Apparently, the GCC equivalent is (not tested):

#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)

BOOST_PP_STRINGIZE seems a excellent solution for C++, but not for regular C.

Here is my solution for 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))

Above definitions result in:

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"

For "defined as interger", "defined as string", and "defined but no value" variables , they work just fine. Only for "not defined" variable, they displayed exactly the same as original variable name. You have to used to it -- or maybe someone can provide a better solution.

Chris Barry

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

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)

See: 3.4 Stringification in the gcc online documentation.

KeyserSoze

As far as I know '#error' only will print strings, in fact you don't even need to use quotes.

Have you tried writing various purposefully incorrect code using "BOOST_VERSION"? Perhaps something like "blah[BOOST_VERSION] = foo;" will tell you something like "string literal 1.2.1 cannot be used as an array address". It won't be a pretty error message, but at least it'll show you the relevant value. You can play around until you find a compile error that does tell you the value.

Ambarish Kumar Shivam

Without boost :

  1. define same macro again and compiler HIMSELF will give warning.

  2. From warning you can see location of the previous definition.

  3. vi file of previous definition .

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 ()
{

}
#define a <::BOOST_VERSION>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::106200': No such file or directory

Works even if preprocess to file is enabled, even if invalid tokens are present:

#define a <::'*/`#>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::'*/`#': No such file or directory
GCC4.x: warning: missing terminating ' character [-Winvalid-pp-token]
#define a <::'*/`#>

In Microsoft C/C++, you can use the built-in _CRT_STRINGIZE() to print constants. Many of my stdafx.h files contain some combination of these:

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

and outputs something like this:

_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

You could also preprocess the source file and see what the preprocessor value evaluates to.

Are you looking for

#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif

Not great if BOOST_VERSION is a string, like I've assumed, but there may also be individual integers defined for the major, minor and revision numbers.

Looking at the output of the preprocessor is the closest thing to the answer you ask for.

I know you've excluded that (and other ways), but I'm not sure why. You have a specific enough problem to solve, but you have not explained why any of the "normal" methods don't work well for you.

You could write a program that prints out BOOST_VERSION and compile and run it as part of your build system. Otherwise, I think you're out of luck.

BOOST_VERSION is defined in the boost header file version.hpp.

Take a look at the Boost documentation as well, regarding how you are using the macro:

In reference to BOOST_VERSION, from 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:

Describes the boost version number in XXYYZZ format such that: (BOOST_VERSION % 100) is the sub-minor version, ((BOOST_VERSION / 100) % 1000) is the minor version, and (BOOST_VERSION / 100000) is the major version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!