将宏参数转换为字符串常量并考虑逗号

ama*_*ang 5 c c++ macros

假设我有一个C宏定义的产品版本,如下所示:

#define FOO_VERSION 1,0,0,1
Run Code Online (Sandbox Code Playgroud)

我想在运行时打印它:

#define STRING_VALUE(x) #x

int main()
{
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这将输出一个字符串"FOO_VERSION",而不是"1,0,0,1".宏参数'FOO_VERSION'未被替换.所以我再次尝试这样:

#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(x) #x

int main()
{
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

它在Visual C++ 2013中有效.

这是一个跨平台的应用程序,尽管只有五行代码.当我使用clang编译代码时,会出现编译时错误:"为类似函数的宏调用提供的参数太多".我猜原因是'FOO_VERSION'中定义的逗号.所以第三个版本:

#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(a, b, c, d) #a "," #b "," #c "," #d

int main()
{
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这段代码在clang中工作,但是Visual C++会输出一个警告:"编译时宏'STRING_VALUE__'的实际参数不够",当然运行时输出不正确.

我的问题:是否定义了这种预处理器行为?我可以使用STRING_VALUE宏的通用版本吗?

M O*_*ehm 10

您可以将参数视为单个可变参数宏:

#define FOO_VERSION 1,0,0,1

#define STRING_VALUE(...) STRING_VALUE__(__VA_ARGS__)
#define STRING_VALUE__(...) #__VA_ARGS__
Run Code Online (Sandbox Code Playgroud)

这似乎适用于gcc和Visual C++.