将va_list或指针传递给va_list?

假设我有一个函数,它接受可变参数( ... )或从另一个这样的函数传递的va_list 。 主要逻辑是在这个函数本身(让我们称之为f1 ),但是我希望它将va_list传递给另一个函数(让我们称之为f2 ),它将确定下一个参数类型,使用va_arg获取它,并正确转换和存储它供调用者使用。

将va_list传递给f2是否足够,或者是否需要将指针传递给va_list。 除非va_list需要是数组类型或者将其位置数据存储在va_list对象指向的位置(而不是在对象本身中),否则我无法看到如何通过值传递它可以允许调用函数( f1 ) “看到” va_arg对被调用函数所做的更改。

任何人都可以阐明这一点吗? 我对标准要求的内容感兴趣,而不是某些特定实现允许的内容。

看起来你需要传递一个指向va_list的指针。 有关详细信息,请参阅C99标准文档第7.15节。特别是,要点3指出:

对象ap可以作为参数传递给另一个函数; 如果该函数使用参数ap调用va_arg宏, 则调用函数中的ap值是不确定的,并且应该在进一步引用ap之前传递给va_end宏。

[我的斜体]

编辑:刚刚注意到标准中的一个脚注:

215)允许创建指向va_list的指针并将该指针传递给另一个函数,在这种情况下,原始函数可以在其他函数返回后进一步使用原始列表

因此,您可以将指针传递给va_list,并在被调用函数中执行va_arg(*va_list_pointer)

在我的理解中,你应该直接传递va_list(而不是指向它的指针)。 这似乎得到了comp.lang.c的支持:

“va_list本身不是一个变量参数列表;它实际上是一个指向一个的指针。也就是说,接受va_list的函数本身不是varargs,反之亦然。”

我觉得这个问题在这个问题上很模糊。 最简单的可能是在标准中查看va_list预定义函数应该如何接收它,例如vsnprintf 。 这显然是有价值的,而不是参考。

标准C库中的函数传递va_list元素本身( man 3 vprintf ):

  #include  int vprintf(const char *format, va_list ap); int vfprintf(FILE *stream, const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); int vsnprintf(char *str, size_t size, const char *format, va_list ap); 

将指针传递给va_list在32位系统中工作正常。 您甚至可以在子例程中一次获取一个参数。 但它似乎不适用于64位系统,会在va_arg()中产生段故障。