问题
I have a C program with a lot of optimizations that can be enabled or disabled with #define
s. When I run my program, I would like to know what macros have been defined at compile time.
So I am trying to write a macro function to print the actual value of a macro. Something like this:
SHOW_DEFINE(X){\
if( IS_DEFINED(X) )\
printf("%s is defined and as the value %d\n", #X, (int)X);\
else\
printf("%s is not defined\n", #X);\
}
However I don't know how to make it work and I suspect it is not possible, does anyone has an idea of how to do it?
(Note that this must compile even when the macro is not defined!)
回答1:
As long as you are willing to put up with the fact that SOMESTRING=SOMESTRING indicates that SOMESTRING has not been defined (view it as the token has not been redefined!?!), then the following should do:
#include <stdio.h>
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x))
#define CHARLIE -6
#define FRED 1
#define HARRY FRED
#define NORBERT ON_HOLIDAY
#define WALLY
int main()
{
SHOW_DEFINE(BERT);
SHOW_DEFINE(CHARLIE);
SHOW_DEFINE(FRED);
SHOW_DEFINE(HARRY);
SHOW_DEFINE(NORBERT);
SHOW_DEFINE(WALLY);
return 0;
}
The output is:
BERT=BERT
CHARLIE=-6
FRED=1
HARRY=1
NORBERT=ON_HOLIDAY
WALLY=
回答2:
Writing a MACRO that expands to another MACRO would require the preprocessor to run twice on it.
That is not done.
You could write a simple file,
// File check-defines.c
int printCompileTimeDefines()
{
#ifdef DEF1
printf ("defined : DEF1\n");
#else // DEF1
printf ("undefined: DEF1\n");
#endif // DEF1
// and so on...
}
Use the same Compile Time define lines on this file as with the other files.
Call the function sometime at the start.
If you have the #DEFINE
lines inside a source file rather than the Makefile
,
Move them to another Header
file and include that header across all source files,
including this check-defines.c
.
Hopefully, you have the same set of defines allowed across all your source files.
Otherwise, it would be prudent to recheck the strategy of your defines.
To automate generation of this function,
you could use the M4 macro language (or even an AWK script actually).
M4 becomes your pre-pre-processor.
回答3:
#ifdef MYMACRO
printf("MYMACRO defined: %d\r\n", MYMACRO);
#endif
I don't think what you are trying to do is possible. You are asking for info at runtime which has been processed before compilation. The string "MYMACRO" means nothing after CPP has expanded it to its value inside your program.
回答4:
You did not specify the compiler you were using. If this is gcc, gcc -E may help you, as it stops after the preprocessing stage, and prints the preprocessing result. If you diff a gcc -E result with the original file, you may get part of what you want.
回答5:
Why not simply testing it with the preprocessor ?
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
One can also embed this in another test not to print it everytime:
#if define(SHOW_DEFINE)
#if defined(X)
printf("%s is defined and as the value %d\n", #X, (int)X);
#else
printf("%s is not defined\n", #X);
#endif
#endif
回答6:
Wave library from boost can be helpful also to do what you want. If your project is big enough, I think it is worth trying. It is a C++ preprocessor, but they are the same any way :)
回答7:
I believe what you are trying to do is not possible. If you are able to change the way your #define
s work, then I suggest something like this:
#define ON 1
#define OFF 2
#define OPTIMIZE_FOO ON
#define OPTIMIZE_BAR OFF
#define SHOW_DEFINE(val)\
if(val == ON) printf(#val" is ON\n");\
else printf(#val" is OFF\n");
回答8:
It is not possible indeed, the problem being the "not defined" part. If you'd relied on the macro values to activate/deactivate parts of your code, then you could simply do:
#define SHOW_DEFINE(X) \
do { \
if (X > 0) \
printf("%s %d\n", #X, (int)X); \
else \
printf("%s not defined\n", #X); \
} while(0)
回答9:
Based on Chrisharris, answer I did this. Though my answer is not very nice it is quite what I wanted.
#define STR(x) #x
#define SHOW_DEFINE(x) printf("%s %s\n", #x, strcmp(STR(x),#x)!=0?"is defined":"is NOT defined")
Only bug I found is the define must not be #define XXX XXX (with XXX equals to XXX).
回答10:
This question is very close from Macro which prints an expression and evaluates it (with __STRING). Chrisharris' answer is very close from the answer to the previous question.
回答11:
you can use an integer variable initialized to 1. multiply the #define with this variable and print the value of variable.
来源:https://stackoverflow.com/questions/1164652/printing-name-and-value-of-a-macro