Reputation: 6604
I'm working on some code that was originally made in MSVC and I'm trying to get it to compile on Clang (using Xcode). The code I've got is something like this:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x##"Map" );\
myRemaps[map##x] = GetHandle( #x##"Remap" );
Currently I'm getting a build error saying that pasting formed the string "Height""Map"
, where I really want "HeightMap"
. This code works on MSVC, is there something about Clang's macro syntax that means this kind of thing needs to be written differently?
Upvotes: 0
Views: 2113
Reputation: 47603
In C, "X""Y"
is equivalent to "XY"
. However, when you write such a thing in a macro:
str1##str2
you are telling the lexer to concat the two as one token. "X""Y"
is actually two tokens that are concatenated by the lexer1, while "X"##"Y"
is supposed to be one token (which is not a valid token).
What you need is to simply drop the ##
:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
1 Or the semantics analyzer, depending on the implementation
Typically, the regex matching a string looks like this (simplified):
"(a|\b)*"
(assume a
is a list of all characters that don't need to be escaped and b
is the others). Probably, for MSVC, it is defined like this:
"(a|\b)*"s*+
(s
is whitespace)
This means that MSVC probably sees "X" "Y"
as one token instead of two.
Upvotes: 3
Reputation: 24440
Just use (#x "Map")
in place of #x##"Map"
. It should work in C++. E.g. this is perfectly valid: ("B" "Map")
and evaluates to "BMap"
.
Upvotes: 2
Reputation: 9388
Try this instead:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
Two string litterals are automatically concatenated by the compiler.
Upvotes: 1
Reputation: 118006
Note that "Height""Map"
actually is the same as "HeightMap"
when parsed. So you can simply use this:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
Upvotes: 1