[comp.lang.c++] varargs and C++

leech@phi.cs.unc.edu (Jonathan Leech) (01/31/88)

    After porting C++ 1.2.1 to our new Sun-4 tonight, I have come to
the conclusion that there is no way to write C++ code using
<varargs.h> in a portable fashion at this time. Part of the SPARC
<varargs.h> looks like this:

#if defined(sparc)
# define va_alist __builtin_va_alist
#endif
# define va_dcl int va_alist;
# define va_start(list) list = (char *) &va_alist
# define va_end(list)
# define va_arg(list,mode) ((mode *)(list += sizeof(mode)))[-1]

    A little hacking proves conclusively what this suggests: that the
compiler recognizes the '__builtin_va_alist' and inserts magic,
presumably to move parameters passed in registers onto the stack.

    Unfortunately, cfront turns the name into '_au0___builtin_va_alist'
and this mechanism is defeated. Thus without hacking cfront itself to
not prefix names like this, straightforward use of varargs will not
work on a Sun 4.

    This is a problem since the libC form() routine requires varargs.
My workaround is to postprocess lib/mk/out..c and restore the
original name.

    I suspect that this whole business with builtins is going to get
more and more annoying as ANSI-compliant C compilers which actually
use builtins extensively start showing up; hopefully AT&T is already
thinking about solutions.

    Jon Leech (leech@cs.unc.edu)    __@/
    ``After all, the best part of a holiday is perhaps not so much to be
      resting yourself as to see all the other fellows busy working.''
	- Kenneth Grahame, _The Wind in the Willows_

powell@ole.UUCP (Gary Powell) (06/12/90)

I need a bit of help. I am setting up a fn which takes varargs
fn (int,...) and I want to recursively call it.  Which means
strip off the first bit of information, decrement the int and
call it again. (until I get to a leaf)

fn (int dim,....)
{
    fn (dim - 1,???)
}

The only way I have figured to do this is build an array and
have another fn g() which does the recursion.

Is there a way to pass the vararg list on down the stack?
-- 
   _Q   _Q    _Q     _Q  _Q_Q    _Q    _Q                                    _Q
  /_\) /_\)  /_\)   /_\)/_/\\)  /_\)  /_\)                    Gary Powell   /_\)
_O|/O_O|/O__O|/O___O|/O_OO|/O__O|/O__O|/O__________________________________O|/O_
uunet!uw-beaver!sumax!ole!powell            Seattle Silicon Corp. (206) 828-4422

fkittred@bbn.com (Fletcher Kittredge) (06/13/90)

In article <1591@ole.UUCP> powell@ole.UUCP (Gary Powell) writes:
>I need a bit of help. I am setting up a fn which takes varargs
>fn (int,...) and I want to recursively call it.  Which means
>strip off the first bit of information, decrement the int and
>call it again. (until I get to a leaf)
>

I don't know which 'version' of C++ you are using, so it is hard
to give exact information, but you should start by RTFM for varargs
and stdargs.  If your system has stdargs, then use it instead of
varargs.

regards,
fletcher


Fletcher E. Kittredge  fkittred@bbn.com
Platforms and Tools Group
BBN Software Products Company
10 Fawcett St.
Cambridge, MA. 02138

wmmiller@cup.portal.com (William Michael Miller) (06/14/90)

powell@old.UUCP (Gary Powell) writes:
> Is there a way to pass the vararg list on down the stack?

The way to do this in ANSI C is to pass the argument pointer (i.e., the
thing declared va_list).  This approach would mean that you would have
something like this:

        #include <stdarg.h>
        void fn(int dim,...) {
           va_list ap;
           va_start(ap, dim);
           fnx(dim, ap);
           va_end(ap);
           }
        void fnx(int dim, va_list ap) {
           sometype x = va_arg(ap, sometype);
           if (dim > 1) {
              fnx(dim-1, ap);
              // ...
              }
           else {
              // process "leaf"
              }
           }

------------------------------------------------------------------------------
William M. Miller, Glockenspiel, Inc.; P. O. Box 366, Sudbury, MA 01776-0003
wmmiller@cup.portal.com         BIX: wmiller            CI$: 72105,1744