在宏定义 (Clang) 中连接两个字符串

Concatenating two strings in macro definition (Clang)

本文关键字:字符串 两个 宏定义 Clang 连接      更新时间:2023-10-16

我正在处理一些最初用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 的宏语法是否意味着这种东西需要以不同的方式编写?

在 C 中,"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" );

编译器会自动连接两个字符串 Illion。