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使用这样的东西啊,注册窗口……)。 可悲的是,我知道没有办法做你想做的事。