Clang 和 MSVC 中不同的宏字符串化规则

问题描述 投票:0回答:2

我发现 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)”,但对我来说,在没有括号的情况下获取它很有趣。

visual-c++ clang c-preprocessor
2个回答
1
投票

以下内容是正确的,并且应该适用于任何符合标准的 C99 编译器:

#define __IN_QUOTES(...) #__VA_ARGS__
#define IN_QUOTES(str) __IN_QUOTES(str)

它适用于我在 Compiler Explorer 上找到的 MSVC 版本(以及 Clang 和 GCC)。

请注意,它不会准确地保留空白,但对此您无能为力。

(我必须将

#ifdef
更改为
#ifdef _MSC_VER
;我尝试过的在线编译器似乎都没有定义
_MSVC_LANG
。)


0
投票

预处理器输入:

#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):

https://compiler-explorer.com/z/Mv94195zT

© www.soinside.com 2019 - 2024. All rights reserved.