views:

147

answers:

2

I need to do two (or more) passes over a va_list. I have a buffer of some size, and I want to write a formatted string with sprintf into it. If the formatted string doesn't fit in the allocated space I want to double the allocated space and repeat until it fits.

(As a side-note, i would like be able to calculate the length of the formatted string first and allocate enough space, but the only function that I found that can do that is _snprintf, and it is deprecated in VS2005 ...)

Now, so far there are no problems: i use vsnprintf and call va_start before each invokation.

But I've also created a function that takes a va_list as a parameter, instead of "...". Then I cannot use va_start again! I've read about va_copy, but it is not supported in VS2005.

So, how would you do this?

+1  A: 

I see of no portable way (and I think that va_copy has been introduced in C99 because there was no portable way to achieve its result in c89). A va_list can be a reference type mock up declared as

typedef struct __va_list va_list[1];

(see gmp for another user of that trick) and that explains a lot of the language constraints around them. BTW, don't forget the va_end if portability is important.

If portability is not important, I'd check stdard.h and see if I can hack something considering the true declaration.

AProgrammer
Ok. If there is no answer, that's also an answer. Thanks.
Jonatan
+1  A: 

A previous question about the lack of va_copy in MSVC had some decent enough suggestions, including to implement your own version of va_copy for use in MSVC:

#define va_copy(d,s) ((d) = (s))

You might want to throw that into a 'portability' header protected by an #ifndef va_copy and #ifdef _MSC_VER for use on VC.

Michael Burr
Thanks, good suggestion, but I'm too nervous to use that. :)
Jonatan