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

6

假设我有一个C语言宏定义的产品版本号如下:

#define FOO_VERSION 1,0,0,1

我想在运行时打印它:

#define STRING_VALUE(x) #x

int main()
{
    std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}

这将输出一个字符串"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;
}

它可以在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;
}
这段代码在clang中可以工作,但是在Visual C++中会输出一个警告:"not enough actual parameters for macro 'STRING_VALUE__'",当然运行时的输出结果也不正确。 我的问题是:这种预处理器的行为是否被定义了?我能否拥有STRING_VALUE宏的通用版本?
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
11

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

#define FOO_VERSION 1,0,0,1

#define STRING_VALUE(...) STRING_VALUE__(__VA_ARGS__)
#define STRING_VALUE__(...) #__VA_ARGS__

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


为什么我没想到那个? - amanjiang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,