onqtam
onqtam

Reputation: 4538

trouble with the preprocessor - when concatenating "name" and "=" as tokens

Here is the code:

#define STR_CONCAT_IMPL(s1, s2) s1##s2
#define STR_CONCAT(s1, s2) STR_CONCAT_IMPL(s1, s2)
#define TOSTR_IMPL(x) #x
#define TOSTR(x) TOSTR_IMPL(x)
#define STR_CONCAT_TOSTR(s1, s2) TOSTR(STR_CONCAT(s1, s2))

int main() {
    const char* a = STR_CONCAT_TOSTR(name, p); // works
    const char* b = STR_CONCAT_TOSTR(name, =); // doesn't work
    return 0;
}

I need a string like "name=" from "name" at compile time (runtime concatenation not an option) so I tried with my old macros but I get this error:

error: pasting "name" and "=" does not give a valid preprocessing token

But when not using = but a normal character - it works.

How can I get this to work?

C++98 GCC/MSVC solution needed.

Upvotes: 1

Views: 56

Answers (2)

Cameron
Cameron

Reputation: 98846

That's because name= isn't a token, it's two. So, unlike with namep, they can't be pasted to produce a single token.

All you need to do is define STR_CONCAT_TOSTR differently to concatenate the string literals of the starting tokens instead of trying to concatenate the tokens first:

#define STR_CONCAT_TOSTR(s1, s2) (TOSTR(s1) TOSTR(s2))

Upvotes: 1

Qaz
Qaz

Reputation: 61970

I'll assume you need a macro for this and can't just use the compiler itself.

Take advantage of adjacent string literals being concatenated:

#define STR_CONCAT_TOSTR(s1, s2) TOSTR(s1) TOSTR(s2)

In this case, STR_CONCAT_TOSTR(name, =) expands to "name" "=", which the compiler turns into "name=".

Upvotes: 5

Related Questions