C varargs – va_copy问题
我在C中编写一个函数,它接受可变数量的参数。
size_t myprintf(char *fmt, ...);
到现在为止还挺好。 我已经决定最好做Right Way™并创建一个带有变量参数的版本,另一个版本带有一个va_list
。
size_t myprintf(char *fmt, ...); size_t myvprintf(char *fmt, va_list args);
没那么难。 除了my_vprintf()
需要将其args
发送到两个不同的函数(首先是长度为0的snprintf()
以确定我们需要多少空间,然后在我们分配了那么多空间之后再到sprintf()
)。 我用va_copy
做这个。
size_t myvprintf(char *fmt, va_list args) { va_list args2; va_copy(args, args2); // do stuff with args2 va_end(args2); // do more stuff with args }
这一切都很好,花花公子,但C99实施起来有点差。 我希望,如果可能的话,我的代码也可以在C89中工作,并且可以与尽可能多的编译器和尽可能多的平台一起工作。 我目前在#include
但在任何代码之前有这个:
#ifndef va_copy # ifdef __va_copy # define va_copy(a,b) __va_copy(a,b) # else /* !__va_copy */ # define va_copy(a,b) ((a)=(b)) # endif /* __va_copy */ #endif /* va_copy */
我被认为((a)=(b))
是不可靠的,我应该使用memcpy()
或类似的东西,但这仍然是“如果你不支持C99,我希望它工作“而不是”如果你不支持C99,永远不要害怕“(这就是我想要的)。 有没有什么好方法可以解决这个限制? 我已经看到了一些解决方案 – 使用一个参数并递归的va_list
函数,两次传递va_list
以便制作两个单独的副本等等 – 但我不知道它们的工作情况如何(并且递归解决方案赢得了’如果我只是想调用vsnprintf()
,那么这样做会好吗,不管吗?)。
所以我转向你,StackOverflow用户。 还有什么我可以做的提供C89兼容性,或者是没有va_copy
和__va_copy
用户(不可否认的是,很少和很远)只是要把它吸入并接受它?
(a)=(b)
不可靠。 即使传递两个va_list
也是(公共函数将是一个简单的包装器),因为va_list可以是这样的:
typedef __va_list_impl va_list[1];
为什么在一个上做一个va_arg会修改另一个(我好像记得Solaris使用这样的东西啊,注册窗口……)。 可悲的是,我知道没有办法做你想做的事。