I'm trying to make some kind of a simple system that calculates the number of builds, including this info in .rc file (for windows) and met the problem. Here it is:
#define QUOTE(s) #s
#define A 0,0,0,1
#define A_STR QUOTE(A)
Expanding of A_STR: "A"
but not "0,0,0,1"
as I expected.
Well, I need A_STR
to be a string representation of A
(that's what windres
expects to see in .rc file), but I can't find the way to do this.
I've already tried smth like #define A_STR #A
but it simply expands to #0,0,0,1
.
I also tried using qmake like this: DEFINES *= A_STR="<here-is-how-I-get-version>"
but gcc
gets it without quotes and I've got the same problem.
When a C preprocessor macro is expanded, its parameters are expanded to their literal arguments, so
s
would be expanded toA
when yourQUOTE(s)
taking argumentA
is expanded. Normally, after this expansion is complete, the expanded text is then scanned again to expand any macros embedded therein, so this would cause theA
to expand to0,0,0,1
. However, when the stringification operator#
is used to stringify the following text, that stringification happens first, so the following text never gets a chance to be expanded, thus you get stringified"A"
as the final expansion ofA_STR
.This problem is normally solved by introducing a second level of indirection, which gives the initial macro argument a second chance to expand:
However, this would not actually work for your case, because in the first-level expansion the
A
would expand to0,0,0,1
, which would be taken as four arguments toQUOTE2()
, and thus would be rejected as an invalid macro call.You can solve this with variadic macro arguments and
__VA_ARGS__
: