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]

Reply via email to