变量参数

va_startva_argva_endva_copy 函数实际上是宏。

一定要始终调用 va_start 第一,也是唯一一次,并最后一次通话 va_end,只有一次,在功能上的每一个出口点。不这样做可能会对你的系统起作用,但肯定不是可移植的,因此会引发错误。

注意正确地声明你的函数,即使用原型,并注意对最后一个非变量参数的限制 (不是 register,不是函数或数组类型)。声明只接受可变参数的函数是不可能的,因为至少需要一个非变量参数才能启动参数处理。

调用 va_arg 时,必须请求提升的参数类型,即:

  • short 被提升为 intunsigned short 也被提升为 int,除非 sizeof(unsigned short) == sizeof(int),在这种情况下它被提升为 unsigned int)。
  • float 晋升为 double
  • signed char 晋升为 int; unsigned char 也被提升为 int,除非 sizeof(unsigned char) == sizeof(int),这种情况很少发生。
  • char 通常被提升为 int
  • uint8_tint16_t 这样的 C99 类型同样被推广。

历史(即 K&R)可变参数处理在 <varargs.h> 中声明,但不应该使用,因为它已经过时了。标准的可变参数处理(在此描述并在 <stdarg.h> 中声明)在 C89 中引入; va_copy 宏是在 C99 中引入的,但在此之前由许多编译器提供。