我发现 MSVC 和 Clang 中的宏字符串化存在差异。是否可以在 Clang 中编写一个与 MSVC 中的字符串化作用相同的字符串化宏?
#define __IN_QUOTES(str) #str
#define IN_QUOTES(str) __IN_QUOTES(str)
#define HELLO_WORLD Hello world
int main()
{
#ifdef _MSVC_LANG
printf("%s", "MSVC\r\n");
#else
printf("%s", "CLANG\r\n");
#endif
printf("%s", IN_QUOTES(HELLO_WORLD));
return 0;
}
此代码在 Clang 和 MSVC 中的工作方式相同,但如果我将第 3 行写为
#define HELLO_WORLD Hello, world
它可以在 MSVC 中编译(输出为“Hello, world”),但不能在 Clang 中编译,并出现错误“为类似函数的宏调用提供了太多参数”。 问题是可以编写 IN_QUOTES 宏来在 Clang 和 MSVC 中生成“Hello, world”吗? 我试过了
#define IN_QUOTES((str)) __IN_QUOTES(str)
它在 Clang 和 MSVC 中返回“(Hello, world)”,但对我来说,在没有括号的情况下获取它很有趣。
以下内容是正确的,并且应该适用于任何符合标准的 C99 编译器:
#define __IN_QUOTES(...) #__VA_ARGS__
#define IN_QUOTES(str) __IN_QUOTES(str)
它适用于我在 Compiler Explorer 上找到的 MSVC 版本(以及 Clang 和 GCC)。
请注意,它不会准确地保留空白,但对此您无能为力。
(我必须将
#ifdef
更改为 #ifdef _MSC_VER
;我尝试过的在线编译器似乎都没有定义 _MSVC_LANG
。)
预处理器输入:
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#pragma message("_MSVC_LANG: " TOSTRING(_MSVC_LANG))
#pragma message("__cplusplus: " TOSTRING(__cplusplus))
#define MY_QSTR "Hello Quoted World"
#define MY_STR Hello Unquoted World
#include <cstdio>
int main() {
printf("_MSC_VER: %s\n", TOSTRING(_MSC_VER));
printf("_MSVC_LANG: %s\n", TOSTRING(_MSVC_LANG));
printf("__cplusplus: %s\n", TOSTRING(__cplusplus));
printf("MY_QSTR: %s\n", MY_QSTR);
printf("TOSTRING(MY_STR): %s\n", TOSTRING(MY_STR));
}
预处理器输出:
#pragma message("_MSVC_LANG: " "201402L")
#pragma message("__cplusplus: " "199711L")
int main() {
printf("_MSC_VER: %s\n", "1938");
printf("_MSVC_LANG: %s\n", "201402L");
printf("__cplusplus: %s\n", "199711L");
printf("MY_QSTR: %s\n", "Hello Quoted World");
printf("TOSTRING(MY_STR): %s\n", "Hello Unquoted World");
}
要在编译器资源管理器上使用
_MSVC_LANG
,您必须选择 C++(而不是 C):