跳转到内容

可变参数宏

本页使用了标题或全文手工转换
维基百科,自由的百科全书
“可变参数宏”的各地常用名称
中国大陆可变参数宏
台湾可变参数巨集

可变参数宏C语言C++语言函数宏的参数个数可以是0个或多个。这一语言特性由C99引入。C++11也开始支持。[1]

声明语法

声明语法类似于可变参数函数:逗号后面三个句点"...",表示一个或多个参数。但常见编译器也允许传递0个参数。[2][3]宏扩展时使用特殊标识符__VA_ARGS__表示所传递的参数的替换。

没办法访问可变参数列表内的单个参数,也不能获知多少个参数被传递。[4]

实现支持

C/C++编译器支持:

尾部逗号

对于可变参数为空情形,Visual Studio[3]直接去掉可变参数前面的逗号;GCC[2]需要在__VA_ARGS__前面放上##以去除逗号。

# define MYLOG(FormatLiteral, ...)  fprintf (stderr, "%s(%d): " FormatLiteral "\n", __FILE__, __LINE__, __VA_ARGS__)

对于

MYLOG("Too many balloons %u", 42);

扩展为:

fprintf (stderr, "%s(%u): " "Too many balloons %u" "\n", __FILE__, __LINE__, 42);

它等价于:

fprintf (stderr, "%s(%u): Too many balloons %u\n", __FILE__, __LINE__, 42);

但对于例子:

MYLOG("Attention!");

扩展为

fprintf (stderr, "%s(%u): " "Attention!" "\n", __FILE__, __LINE__, );

GCC将会编译报错.

GCC支持下述不可移植的扩展:

# define MYLOG(FormatLiteral, ...)  fprintf (stderr, "%s(%u): " FormatLiteral "\n", __FILE__, __LINE__, ##__VA_ARGS__)

这将删除空的__VA_ARGS__尾部逗号。

参见

参考文献

  1. ^ Working draft changes for C99 preprocessor synchronization – http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm页面存档备份,存于互联网档案馆
  2. ^ 2.0 2.1 2.2 Variadic Macros – Using the GNU Compiler Collection (GCC). GNU Compiler Collection. [2017-04-01]. (原始内容存档于2020-07-04). 
  3. ^ 3.0 3.1 3.2 Variadic Macros (C++). [2017-04-01]. (原始内容存档于2016-06-11). 
  4. ^ Laurent Deniau. __VA_NARG__ - comp.std.c - Google Groups. groups.google.com. 2006-01-16. Usenet: [email protected]. (原始内容存档于2012-11-07). 
  5. ^ Clang source code change that mentions __VA_ARGS__ support (2006-07-29), note that Clang was open-sourced in 2007. http://llvm.org/viewvc/llvm-project?view=revision&revision=38770[失效链接]
  6. ^ Sun Studio feature comparison – http://developers.sun.com/sunstudio/support/CCcompare.html页面存档备份,存于互联网档案馆