Я работаю над некоторым кодом, который был первоначально сделан в MSVC, и я пытаюсь заставить его скомпилировать на Clang (используя Xcode). Код, который я получил, выглядит примерно так:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x##"Map" );\
myRemaps[map##x] = GetHandle( #x##"Remap" );
В настоящее время я получаю сообщение об ошибке, утверждающее, что вставка сформировала строку "Height""Map"
где я очень хочу "HeightMap"
, Этот код работает на MSVC, есть ли что-то в макросе Clang для синтаксиса, что означает, что такие вещи нужно писать по-другому?
В С, "X""Y"
эквивалентно "XY"
, Однако, когда вы пишете такую вещь в макросе:
str1##str2
вы говорите лексеру конкатировать как один знак. "X""Y"
на самом деле два токена, которые соединяются лексером1, в то время как "X"##"Y"
должен быть одним токеном (который не является действительным токеном).
Что вам нужно, это просто бросить ##
:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
1 Или анализатор семантики, в зависимости от реализации
Как правило, регулярное выражение, соответствующее строке, выглядит так (упрощенно):
"(a|\b)*"
(предполагать a
это список всех символов, которые не нужно экранировать и b
это другие). Вероятно, для MSVC это определяется так:
"(a|\b)*"s*+
(s
это пробел)
Это означает, что MSVC, вероятно, видит "X" "Y"
как один жетон вместо двух.
Просто используйте (#x "Map")
на месте #x##"Map"
, Это должно работать в C ++. Например. это совершенно верно: ("B" "Map")
и оценивает "BMap"
,
Обратите внимание, что "Height""Map"
на самом деле так же, как "HeightMap"
когда разбирается. Так что вы можете просто использовать это:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
Попробуйте это вместо этого:
#define DO_MAPPING(x,y,z)\
myMaps[map##x] = GetTex( #x "Map" );\
myRemaps[map##x] = GetHandle( #x "Remap" );
Две строковые литералы автоматически объединяются компилятором.