On 17 Feb 2006 01:45:37 -0800, "pi************@gmail.com"
<pi************@gmail.com> wrote:
Can I use printf inside a variadic function that I am writing?
Yes. As long as you declare it correctly, by #include'ing <stdio.h>,
as you must for _any_ call to it.
Like:
void print(const char * format,...)
{
va_list va;
va_start(va, format);
char buffer[64*1024]; // yeah, I know...
vsprintf(buffer, format, va);
va_end(va);
printf("--- %s ---", buffer);
}
I know the example is degenerate, but is it allowed, that is, does it
have welldefined behavior?
As long as a similar direct call to s[n]printf would, namely: you
don't overflow buffer, a risk you already alluded to, and could
protect against in C99 by using vsnprintf; and the data arguments you
receive and pass on using va correctly match the format specifiers.
(And don't overlap, but nothing validly provided by the caller can
overlap your 'auto' buffer.) And you don't overflow the stack.
I would imagine that printf itself would also have need for the
va_list, va_start etc. mechanism.
No problem; varargs works separately for each vararg function. You can
have vararg call vararg, vararg call nonvararg, vararg call nonvararg
that calls vararg, etc., etc. The only thing you can't do is pass your
own varargs on to another routine _as varargs_; instead you pass the
entire list (or a suffix of it) as a va_list -- as you correctly do.
The other thing to be careful of is that you can't pass 'your' va_list
to a function that uses it to access the arguments (like vs[n]printf
usually) _and_ use that same va_list to access the arguments yourself,
because it is unspecified whether va_list is an array 'by reference'
type or not. In C99 you can use va_copy to handle this. Or, even in
C89, you can start, use and end two va_list objects explicitly; or one
object with distinct (non-overlapping) ranges.
Oh, and to be super-picky: your 64*1024 is nominally done in 'int'
arithmetic, which is allowed to be only 1+15 bits and could overflow.
In practice this will always be done at compile time and should be at
least diagnosed, but is not strictly required to be. Moreover, 65536
chars is greater than the minimum object size that must be supported,
even (very slightly) in C99, and exceeding a resource limit isn't
required to be diagnosed, although compile-time cases should be.
And finally, it is implementation-dependent whether the last line of a
text stream (which stdout is) must end in a newline. Your function by
itself is valid, but if used in a program that does not subsequently
output a newline on such a system it won't work as desired.
- David.Thompson1 at worldnet.att.net