我正在用 C 语言编写一个函数,它接受可变数量的参数。
size_t myprintf(char *fmt, ...);
到目前为止,一切都很好。我决定最好以正确的方式做事,并制作一个采用可变参数的版本,以及另一个采用va_list
.
size_t myprintf(char *fmt, ...);
size_t myvprintf(char *fmt, va_list args);
并不难做到。除了my_vprintf()
需要发送其args
输出到两个不同的函数(首先是snprintf()
长度为 0 来确定我们需要多少空间,然后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 <stddef.h>
但在任何代码之前:
#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
and __va_copy
(诚然,数量很少且相距甚远)只是将其吸进去并接受它?