You have two problems. The first is that preprocessor tokens inside quotes (i.e. string literals) aren't substituted. The second is that you must defer the actual stringification until all preprocessing tokens have been replaced. The stringification must be the very last macro that the preprocessor deals with.
Token substitution happens iterativly. The preprocessor deals with the substitution, and then goes back to see if there is anything left to substitute in the sequence it just replaced. We need to use it to our advantage. If we have an hypothetical TO_STRING
macro, we need the very next iteration to substitute all preprocessing tokens, and only the one after that to produce a call to the "real" stringification. Fortunately, it's fairly simple to write:
#define TO_STRING(...) DEFER(TO_STRING_)(__VA_ARGS__)
#define DEFER(x) x
#define TO_STRING_(...) #__VA_ARGS__
#define SOME_CONSTANT 64
#define QUOTE(...) TO_STRING(__VA_ARGS__)
const char * aString = QUOTE({
"key":"fred",
"value": TO_STRING(SOME_CONSTANT)
});
Live example
We need the DEFER
macro because the preprocessor won't substitute inside something that it recognizes as an argument to another macro. The trick here, is that the x
in DEFER(TO_STRING_)(x)
is not an argument to a macro. So it's substituted in the same go as DEFER(TO_STRING_)
. And what we get as a result is TO_STRING_(substituted_x)
. That becomes a macro invocation in the next iteration. So the preprocessor will perform the substitution dictated by TO_STRING_
, on the previously substituted x
.