C/C++ Macro string concatenation

2019-01-01 08:28发布

#define STR1      "s"
#define STR2      "1"
#define STR3      STR1 ## STR2

Is it possible to concatenate have STR3 == "s1"? You can do this by passing args to another Macro function. But is there a direct way?

3条回答
无色无味的生活
2楼-- · 2019-01-01 09:16

You don't need that sort of solution for string literals, since they are concatenated at the language level, and it wouldn't work anyway because "s""1" isn't a valid preprocessor token. However, for general token pasting, try this:

/*
 * Concatenate preprocessor tokens A and B without expanding macro definitions
 * (however, if invoked from a macro, macro arguments are expanded).
 */
#define PPCAT_NX(A, B) A ## B

/*
 * Concatenate preprocessor tokens A and B after macro-expanding them.
 */
#define PPCAT(A, B) PPCAT_NX(A, B)

Then, e.g., PPCAT(s, 1) produces the identifier s1.

Continuing on the theme are these macros:

/*
 * Turn A into a string literal without expanding macro definitions
 * (however, if invoked from a macro, macro arguments are expanded).
 */
#define STRINGIZE_NX(A) #A

/*
 * Turn A into a string literal after macro-expanding it.
 */
#define STRINGIZE(A) STRINGIZE_NX(A)

Then,

#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
查看更多
浅入江南
3楼-- · 2019-01-01 09:19

Hint: The STRINGIZE macro above is cool, but if you make a mistake and its argument isn't a macro - you had a typo in the name, or forgot to #include the header file - then the compiler will happily put the purported macro name into the string with no error.

If you intend that the argument to STRINGIZE is always a macro with a normal C value, then

#define STRINGIZE(A) ((A),STRINGIZE_NX(A))

will expand it once and check it for validity, discard that, and then expand it again into a string.

It took me a while to figure out why STRINGIZE(ENOENT) was ending up as "ENOENT" instead of "2"... I hadn't included errno.h.

查看更多
零度萤火
4楼-- · 2019-01-01 09:21

If they're both strings you can just do:

#define STR3 STR1 STR2

The preprocessor automatically concatenates adjacent strings.

EDIT:

As noted below, it's not the preprocessor but the compiler that does the concatenation.

查看更多
登录 后发表回答