Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you use C/C++ preprocessor tokens in multiline string literals

Extending on this question and this question , is it possible to have a multiline string literal using either the preprocessor method shown or C++ multiline string literals that contain the values of a preprocessor symbol. For example:

#define SOME_CONSTANT 64

#define QUOTE(...) #__VA_ARGS__
const char * aString = QUOTE(
{
    "key":"fred",
    "value":"SOME_CONSTANT"
}
);

Ideally I want "SOME_CONSTANT" to be replaced with "64".

I have tried using all the tricks in my limited skill set including stringizing and have had no luck.

Any ideas?

like image 374
Ashley Duncan Avatar asked Dec 19 '25 13:12

Ashley Duncan


1 Answers

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.

like image 196
StoryTeller - Unslander Monica Avatar answered Dec 22 '25 01:12

StoryTeller - Unslander Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!