Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to have the C Preprocessor resolve macros in an #error statement?

Just as the title says. I want to use a preprocessor macro in the text of an #error statement:

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #error "SOME_MACRO was not 0; it was [value of SOME_MACRO]"
#endif

In this example I want the preprocessor to resolve [value of SOME_MACRO] to the actual value of SOME_MACRO which in this case is 1. This should happen before the preprocessor, compiler or whatever processes #error prints the error output
Is there a way to do that or is this just not possible?

I don't want to know if there is an ISO C++ standard way to do that, because afaik the preprocessor directive #error is not stated in any ISO C++ standard. However, I know GCC and Visual C++ support #error. But my question is not specific to those compilers, I'm just curious if any C/C++ compiler/preprocessor can do that.

I tried to search for that topic but without any luck.

like image 793
Madio Avatar asked May 14 '11 14:05

Madio


People also ask

Can you use a macro in a macro C?

Short answer yes. You can nest defines and macros like that - as many levels as you want as long as it isn't recursive. Is order important?

Can a macro call itself in C?

You can't have recursive macros in C or C++.

What is parameterized macro in C?

A parameterized macro is a macro that is able to insert given objects into its expansion. This gives the macro some of the power of a function. As a simple example, in the C programming language, this is a typical macro that is not a parameterized macro: #define PI 3.14159.

What are conditional preprocessing macro?

A conditional is a directive that instructs the preprocessor to select whether or not to include a chunk of code in the final token stream passed to the compiler.


2 Answers

For completeness the C++0x way I suggested (using the same trick as Kirill):

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

#define EXPECT(v,a) static_assert((v)==(a), "Expecting " #v "==" STRING(a) " [" #v ": "  STRING(v) "]")


#define VALUE 1

EXPECT(VALUE, 0);

Gives:

g++ -Wall -Wextra -std=c++0x test.cc                     
test.cc:9: error: static assertion failed: "Expecting VALUE==0 [VALUE: 1]"
like image 75
Flexo Avatar answered Oct 10 '22 23:10

Flexo


In Visual Studio you can use pragmamessage as follows:

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

#define SOME_MACRO 1

#if SOME_MACRO != 0
    #pragma message ( "SOME_MACRO was not 0; it was " STRING(SOME_MACRO) )
    #error SOME_MACRO was not 0;
#endif

This will generate two messages, but you'll get the value of SOME_MACRO. In G++ use the following instead (from comments: g++ version 4.3.4 works well with parenthesis as in the code above):

#pragma message "SOME_MACRO was not 0; it was " STRING(SOME_MACRO)
like image 43
Kirill V. Lyadvinsky Avatar answered Oct 10 '22 23:10

Kirill V. Lyadvinsky