Search code examples
c++xcode4macrosclang

Concatenating two strings in macro definition (Clang)


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?


Solution

  • 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.