apalopohapa
apalopohapa

Reputation: 5183

Is it possible to print a preprocessor variable in C?

Is is possible to print to stderr the value of a preprocessor variable in C? For example, what I have right now is:

#define PP_VAR (10)
#if (PP_VAR > 10)
    #warning PP_VAR is greater than 10
#endif

But what I'd like to do is:

#define PP_VAR (10)
#if (PP_VAR > 10)
    #warning PP_VAR=%PP_VAR%
#endif

Is something like this possible in C?

Upvotes: 59

Views: 50427

Answers (5)

Michael Aaron Safyan
Michael Aaron Safyan

Reputation: 95449

Well, what you are doing is actually non-standard. Firstly, the #warning or #warn directive is not standard. Secondly, when using the preprocessor, the line must begin with the pound symbol, without any spaces:

#ifdef BLAH1
#    define BLAH2 // OK, because pound is at the very left.
#endif

#ifdef BLAH3
     #define BLAH4 // Works on many compilers, but is non-standard.
#endif

Since you are already using a non-standard extension, you will need to look up the documentation of the particular preprocessor/compiler that you are using to see what it says about #warning.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

Many C compilers support #warning, but it is not defined by the C standard unless you're using C23 or later.

However, GCC at least does not do pre-processing on the data that follows, which means it is hard to see the value of a variable.

#define PP_VAR 123
#warning "Value of PP_VAR = " PP_VAR
#warning "Value of PP_VAR = " #PP_VAR
#warning "Value of PP_VAR = " ##PP_VAR

GCC produces:

x.c:2:2: warning: #warning "Value of PP_VAR = " PP_VAR
x.c:3:2: warning: #warning "Value of PP_VAR = " #PP_VAR
x.c:4:2: warning: #warning "Value of PP_VAR = " ##PP_VAR

The C23 standard is expected to say:

§6.10.6 Diagnostic directives

Semantics

A preprocessing directive of either form

# error pp-tokensopt new-line
# warning pp-tokensopt new-line

causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens.

Since it specifies that the diagnostic message includes the preprocessing tokens, macros will not be expanded in the message for either #error or #warning. None of the standards that specify #error explicitly specify that the compilation of the translation unit should fail if the directive is executed — only that a diagnostic shall be produced. Nevertheless, there is a reasonable expectation that if a #error directive is executed, the TU should fail to compile. By contrast, executing a #warning directive should not cause the compilation of the TU to fail.

Upvotes: 6

Marc Abramowitz
Marc Abramowitz

Reputation: 3577

This works with GCC 4.4.3:

#define STRING2(x) #x
#define STRING(x) STRING2(x)
#pragma message "LIBMEMCACHED_VERSION_HEX = " STRING(LIBMEMCACHED_VERSION_HEX)

yields:

src/_pylibmcmodule.c:1843: note: #pragma message: LIBMEMCACHED_VERSION_HEX = 0x01000017

Upvotes: 23

MattM
MattM

Reputation: 939

You can print out the value of a preprocessor variable under visual studio. The following prints out the value of _MSC_VER:

#define STRING2(x) #x
#define STRING(x) STRING2(x)

#pragma message(STRING(_MSC_VER))

Not sure how standard this is though.

Upvotes: 68

rtenhove
rtenhove

Reputation: 185

Use the preprocessor token-pasting operator: ##TOKEN_NAME

As previously noted, the preprocessor directives you are using are non-standard, so YMMV.

Upvotes: 3

Related Questions