2010-07-30 69 views
17

假设我有一个函数,它从另一个这样的函数传递可变参数(...)或va_list。主要逻辑是在这个函数本身(我们称之为f1),但我想让它通过va_list到另一个函数(我们称之为f2),它将确定下一个参数类型,使用va_arg获得它,并正确地转换和存储它供呼叫者使用。将va_list或指针传递给va_list?

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

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

回答

23

看起来您需要将指针传递给va_list。有关详细信息,请参阅C99 standard document部7.15.In特别地,项目符号点3种状态:

对象AP可以作为参数传递给 另一个函数被传递;如果该函数调用与参数AP的va_arg宏中在调用函数AP的 值是不确定的,并应被传递到va_end用来 宏之前的任何进一步参照AP

[我的斜体]

编辑:只注意到在标准脚注:

215)它被允许创建一个指针的va_list和指针传递给另一个函数,在这种情况下, 原有的功能可以在其他功能后要进一步利用原有列表返回

所以你可以传递一个指向va_list的和被调用函数做va_arg(*va_list_pointer)

+0

同意你最后一次编辑 - 指针是要走的路(因为OP希望对'va_list'的更改在调用函数中明确可见)。 – caf 2010-07-30 08:48:19

+0

@caf:我不认为你应该编辑出我对'vfprintf()'的引用,因为它看起来像别人正在犯同样的错误,并建议提问者看看现有的原型(实际上并没有回答他的问题)。 – JeremyP 2010-07-30 09:18:59

+2

我会说留下评论和/或投票他们然后 - 它似乎更好有正确的答案不混淆与更早的,不正确的假设... – caf 2010-07-30 12:05:33

2

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

“的va_list本身不是一个变量参数列表,它真的排序的指针,一个是,它接受的va_list功能本身并不是可变参数,也没有副反之亦然“。

+0

我不认为这句话支持你的论点。没有什么关于它不允许将指针传递给'va_list',并且实际上标准明确地说这是允许的。 – caf 2010-07-30 12:08:10

2

我觉得这个问题的文字很模糊。最简单的方法可能是查看标准va_list应该接收的预定义函数,例如vsnprintf。这显然是有价值的,而不是参考。在标准C库通va_list元件本身

+1

标准函数不打算被调用的方式OP想要 - 在被调用之后,'va_list'不能再使用,只能传递给'va_end()'。 – caf 2010-07-30 12:07:11

+0

事实上,我是OP,我同意caf在这一个。 JeremyP是唯一一个似乎引用了任何证据的人,标准很清楚你必须为我想要的语义传递一个指针。 – 2010-07-30 12:28:12

0

功能(man 3 vprintf):

#include <stdarg.h> 

    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); 
+1

这些函数都不打算以OP的方式调用 - 在调用这些函数后,'va_list'不能再使用,只能传递给'va_end()'。 – caf 2010-07-30 12:06:55

0

指针传递到va_list的在32位的系统正常工作。您甚至可以在子例程中一次读取一个参数。 但它似乎在64位系统中不起作用,会在va_arg()处产生段错误。