I am writing a function in C that takes a variable number of arguments.
size_t myprintf(char *fmt, ...);
So far so good. I decided it was best to do Right Way β’ things and create a version that accepts variable arguments, and another version that accepts va_list .
size_t myprintf(char *fmt, ...); size_t myvprintf(char *fmt, va_list args);
Not so hard. With the exception of my_vprintf() you need to send it args out to two different functions (first up to snprintf() with a length of 0 to determine how much space we need, and then sprintf() after we allocated so much space). I am doing this with va_copy .
size_t myvprintf(char *fmt, va_list args) { va_list args2; va_copy(args, args2);
It's all fine and dandy, but the C99 is a little poorly implemented. I would like, if possible, to use my code to work on C89 and work with as many compilers and on as many platforms as possible. I have this after #include <stddef.h> , but before any code:
#ifndef va_copy # ifdef __va_copy # define va_copy(a,b) __va_copy(a,b) # else # define va_copy(a,b) ((a)=(b)) # endif #endif
I am convinced that ((a)=(b)) unreliable and that I should use memcpy() or something like that, but it's still at the level of βIf you do not support C99, I hope it worksβ a not "If you do not support C99, never be afraid" (this is what I want). Is there a good way around this limitation? I saw several solutions - va_list functions that eat one argument and recurs by passing va_list twice to make two separate copies, etc. - but I donβt know how much they will work (and the recursive solution will not be so good if I just want to call vsnprintf() , now will it be?).
So, I am contacting you, a StackOverflow user. Is there anything else I can do to ensure compatibility with C89, or users without va_copy and __va_copy (admittedly few and far apart) to just suck it and take it?