Chr*_*utz 6 c variadic-functions
我在C中编写一个函数,它接受可变数量的参数.
size_t myprintf(char *fmt, ...);
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我已经决定最好做Right Way™并制作一个带有可变参数的版本,另一个版本需要一个va_list.
size_t myprintf(char *fmt, ...);
size_t myvprintf(char *fmt, va_list args);
Run Code Online (Sandbox Code Playgroud)
没那么难.除了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
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,花花公子,但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 */
Run Code Online (Sandbox Code Playgroud)
我被引导相信这((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];
Run Code Online (Sandbox Code Playgroud)
为此,在其中一个上执行 va_arg 将修改另一个(我似乎记得 Solaris 使用这种东西,啊,寄存器 windows...)。可悲的是,我不知道有什么确定的方法可以做你想做的事。