Yes you can, but macro substitution may look a little strange. A replacement with two macros exists for some reason, and if you think about it for a while, it will become clear why this is necessary.
#define STRINGIZER_(exp) #exp #define STRINGIZER(exp) STRINGIZER_(exp) #define NUM 1234 int main(int argc, char *argv[]) { const char *p = STRINGIZER(NUM); printf("%s\n",p); return EXIT_SUCCESS; }
Launch:
1234
The reason for the double replacement: at first glance, you might think that this will solve the problem:
#define STRINGIZER(exp) #exp #define NUM 1234 int main(int argc, char *argv[]) { const char *p = STRINGIZER(NUM); printf("%s\n",p); return EXIT_SUCCESS; }
But it gives:
NUM
what we are not trying to do. If you want the actual extension of the NUM macro to be the first, then this is what you need to do: force extension. Forcing the preprocessor to be replaced first through an intermediate extension (as I will show at the top of this answer), the macro of the passed first expands and then builds.
Sidebar: This method is especially useful for generating wide-format wide-char preprocessor macros that otherwise save regular lines. For example, the __FILE__ macro. Suppose you need a wide char version (a string added with 'L'). At first you might think that this would work:
#define WIDESTR(str) L##str
but expanding this with __FILE__ , as in:
const wchar *p = WIDESTR(__FILE__);
will result in a compiler error: "Undefined identifier: L__FILE__"
So how can we solve this? Similarly, we did the above.
#define WIDESTR_(str) L##str #define WIDESTR(str) WIDESTR_(str) int main(int argc, char *argv[]) { const wchar_t* p = WIDESTR(__FILE__); wcout << p << endl; return EXIT_SUCCESS; }
On my system, this produces:
/Users/craig/tmp/main/main/test.cpp
In closing ...
As a consolation prize, we combine everything in this answer into one giant corn, which we assume when we do this:
int main() { const wchar_t *p = WIDESTR(STRINGIZE(NUM)); wcout << p << endl; return EXIST_SUCCESS; }