【问题标题】:C++ Preprocessor Stringize - Different between GCC and MSVCC++ 预处理器字符串化 - GCC 和 MSVC 之间的区别
【发布时间】:2022-09-24 19:46:17
【问题描述】:

在以下示例中,MSVC 和 GCC 的输出不同。有人可以指出我正确的方向以了解原因吗?

#define TO_STRING(...) #__VA_ARGS__
#define QUOTE(...) TO_STRING(__VA_ARGS__)

#define KEY1 "Key1"
#define KEY2 "Key2"
#define KEY3 "Key3"
#define LEN1 32
#define LEN2 32


const char * cNVKeysMetaData = QUOTE(
{
    "Area1":[ 
        {
            "key":KEY1,
            "maxLength":LEN1,
            "type":"s",
            "default":"Hello"
        },
#if defined(TEST)
        {
            "key":KEY2,
            "maxLength":LEN2,
            "type":"s",
            "default":"invalid"
        },
#endif
        {
            "key":KEY3,
            "maxLength":64,
            "type":"s",
            "default":"invalid"
        }
    ]
}
);

#include <iostream>

int main()
{
    std::cout << cNVKeysMetaData << std::endl;
    return 0;
}

海合会输出:

{ "Area1":[ { "key":"Key1", "maxLength":32, "type":"s", "default":"Hello" }, { "key":"Key3", "maxLength":64, "type":"s", "default":"invalid" } ] }

MSVC 输出:

{ "Area1":[ { "key":"Key1", "maxLength":32, "type":"s", "default":"Hello" }, #if defined(TEST) { "key":"Key2", "maxLength":32, "type":"s", "default":"invalid" }, #endif { "key":"Key3", "maxLength":64, "type":"s", "default":"invalid" } ] }

请注意,MSVC 确实替换了宏 KEY1 等,但没有去掉#if。 GCC 确实去掉了#if。

【问题讨论】:

  • @Peter,这是一个完全可重现的例子!将其直接粘贴到 godbolt.org 并选择最新的 GCC 或 MSVC 编译器。包括所有宏定义。
  • @Peter我不确定你的意思。这是一个mre godbolt.org/z/a6hYPh9ax
  • 谢谢@cigien。只是在上面的示例中向其他人说明 /E 标志会阻止编译,因此需要将其删除以查看编译后的输出。
  • 我认为现在所有的 C++ 爱好者都会在这之上!

标签: c++ c-preprocessor


【解决方案1】:

根据 C/C++: How should preprocessor directive work on macros argument list? ,您不能将预处理器指令(如 #if)放入宏参数列表中。您的代码的行为是未定义的。

我想我会这样做:

#ifdef TEST
#define IF_TEST(...) __VA_ARGS__
#else
#define IF_TEST(...)
#endif

QUOTE(
 ....
 IF_TEST(
        {
            "key":KEY2,
            "maxLength":LEN2,
            "type":"s",
            "default":"invalid"
        },
  )
  ...
)

【讨论】:

  • 谢谢,这是个好建议。幸运的是,在我的情况下,我在实际应用程序(一个非常大的文件)中没有很多不同的测试要做,所以这在实践中是一个合适的解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-08-11
  • 2012-07-13
  • 1970-01-01
  • 2019-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
相关资源
最近更新 更多