On Mon, 16 Dec 2002, Steve Fink wrote:
> I'm a little confused by the va_list* stuff for sprintf*. At one
> point, people were saying that ppc does va_list differently, though
> I'm guessing that was a different compiler than gcc. Now, it seems
> like everything uses the same mechanism (and it was just patched to be
> this way by Dan).
Here's the relevant excerpt from the glibc stdarg(3) man page:
va_copy
An obvious implementation would have a va_list a pointer
to the stack frame of the variadic function. In such a
setup (by far the most common) there seems nothing against
an assignment
va_list aq = ap;
Unfortunately, there are also systems that make it an
array of pointers (of length 1), and there one needs
va_list aq;
*aq = *ap;
Finally, on systems where parameters are passed in regis-
ters, it may be necessary for va_start to allocate memory,
store the parameters there, and also an indication of
which parameter is next, so that va_arg can step through
the list. Now va_end can free the allocated memory again.
To accommodate this situation, C99 adds a macro va_copy,
so that the above assignment can be replaced by
va_list aq;
va_copy(aq, ap);
...
va_end(aq);
Each invocation of va_copy must be matched by a corre-
sponding invocation of va_end in the same function. Some
systems that do not supply va_copy have __va_copy instead,
since that was the name used in the draft proposal.
Hence, the portable thing to do is to treat va_list as an opaque type.
The Configure issue is that not everyone has va_copy, hence Configure
probes are needed for va_copy (and possibly __va_copy.)
One could simply test for va_copy, and, if present, always use it.
Alternatively, the way perl-5.8.0 handles this is to see if varargs
handling without va_copy works. If it doesn't work, then Configure
defines NEED_VA_COPY. Then, in one of the header files (handy.h), there
is the following:
#ifdef NEED_VA_COPY
# ifdef va_copy
# define Perl_va_copy(s, d) va_copy(d, s)
# else
# if defined(__va_copy)
# define Perl_va_copy(s, d) __va_copy(d, s)
# else
# define Perl_va_copy(s, d) Copy(s, d, 1, va_list)
# endif
# endif
#endif
--
Andy Dougherty [EMAIL PROTECTED]