34

对于调试构建,我通常使用 Clang,因为它可以更好地格式化警告和错误,并且更容易跟踪和修复它们。

但是最近在添加了一个带有可变参数的宏之后,Clang 告诉我以下内容(来自一个虚拟项目):

main.cpp:5:20: warning: named variadic macros are a GNU extension [-Wvariadic-macros]
#define stuff3(args...)  stuff_i(args)

我知道macroname(args...)在各种编译器中都能很好地编译,包括 Visualstudio、Sunstudio,当然还有 GCC。但为了确保 clang 是正确的,我尝试了另外两种扩展可变参数的方法:

1号:

#define stuff1(...)  stuff_i(...)

2号:

#define stuff2(...)  stuff_i(__VA_ARGS__)

在这两个我收到此消息:

main.cpp:3:16: warning: variadic macros were introduced in C99 [-Wvariadic-macros]

...这让我想知道可变参数宏是否实际上是 C++ 标准的一部分(当然我知道预处理器是独立解释的)?

4

4 回答 4

41

引用维基百科

可变参数宏于 1999 年在 C 语言标准的 ISO/IEC 9899:1999 (C99) 修订版和 2011 年在 C++ 语言标准的 ISO/IEC 14882:2011 (C++11) 修订版中引入。

所以它是从 C99 和 C++11 开始的标准,但在 C++03 中是 GNU 扩展。

于 2011-01-24T20:14:22.847 回答
30

从 C++11 开始,可变参数宏现在包含在标准 C++ 中。C++11 标准的第 16.3 节指定了可变参数宏,以便它们与 C99 中的可变参数宏兼容(问题中的第二种形式)。

以下是 C++ 中符合标准的可变参数宏定义的示例:

#define foo(x, y, ...)    bar(x, y, __VA_ARGS__)
于 2012-03-08T16:34:03.753 回答
4

以您的示例“数字 2”的形式,它们在 C99 中是标准的,通常 C++ 编译器的预处理器对于 C 和 C++ 编译是相同的。

尽管 Microsoft VC++ 在其他方面顽固地抵制 C99 合规性,但它们也受到支持。因此,在这和 GCC 之间,几乎没有理由避免使用它们。即使在我使用的大多数嵌入式系统编译器上,它们也受支持。

但是,请避免使用“数字 1”形式,它是 GCC 特定的,毫无疑问已被弃用。

于 2011-01-24T20:52:42.433 回答
0

标准在16.3 宏替换中说:

标识符 _ _ VA_ARGS _ _ 应仅出现在在参数中使用省略号的类函数宏的替换列表中。

于 2012-03-06T17:22:34.933 回答