Path: utzoo!utgpu!news-server.csri.toronto.edu!mailrus!uwm.edu!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!snorkelwacker!bloom-beacon!news From: scs@adam.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: passing variable arguments Message-ID: <1990Jun12.014105.13959@athena.mit.edu> Date: 12 Jun 90 01:41:05 GMT References: <353@ankh.ftl.fl.us> <314@ndla.UUCP> Sender: news@athena.mit.edu (News system) Reply-To: scs@adam.mit.edu (Steve Summit) Organization: Thermal Technologies, Inc. Lines: 72 This topic is discussed in the frequently-asked questions list (question 25 in the June posting). Additionally, Tim McDaniel posted a number of corrections and explanations, in article , to some previously- posted code. In article <314@ndla.UUCP> platt@ndla.UUCP (Daniel E. Platt) writes: >... > /* get a pointer to the stack */ > ... >C is set up to put the first argument on the top of the 'stack' (if >there is one). ...but there might not be one, and even if there is one there is no guarantee how it might be set up, which is why... >...this isn't portable. There are macro standards set up to handle this >called 'varargs.' The new, standard macro package (ANSI C) is called . Don't try to pick arguments apart "by hand;" use the standard macro package. If your compiler doesn't supply it yet, you may be able to make use of someone else's implementation of stdarg.h . This is not guaranteed to work, as the innards of a standard header may be tied to a particular implementation (particularly for something as machine-dependent as variable-length argument lists), but it is possible to write a semiportable stdarg.h that will work anywhere a "standard" macro-only (i.e. no special-cased compiler support) varargs.h would work. I posted one to alt.sources some time ago. An amended version is attached. (If stdarg.h is not an option, you could also try using the old varargs package, with which stdarg is partly compatible). Steve Summit scs@adam.mit.edu ----8<------8<----cut here for simple stdarg.h----8<------8<----- /* * stdarg implementation for "conventional" architectures with * downward-growing stacks. The stack is assumed to be aligned * to word, i.e. int, sized boundaries, with smaller arguments * widened when passed and larger arguments equal to (or rounded * up to) a multiple of the word size. * Note that this code (and indeed, any simple macro-based * approach) cannot possibly work on architectures which pass * arguments in registers. * * Another problem is that it doesn't (and can't, without help * from the compiler) know that float arguments are widened to double * when passed. Don't, therefore, call va_arg(..., float). * * Steve Summit 4/15/89 * * This code is Copyright 1989 by Steve Summit. * It may, however, be redistributed and used without restriction. */ typedef int __stacktype; typedef char __argptype; typedef __argptype *va_list; #define __argsize(thing) ((sizeof(thing) + (sizeof(__stacktype) - 1)) \ / sizeof(__stacktype) * (sizeof(__stacktype) / sizeof(__argptype))) #define va_start(vaptr, lastarg) \ vaptr = (va_list)&lastarg + __argsize(lastarg) #define va_arg(vaptr, type) \ (*(type *)(((vaptr) += __argsize(type)) - __argsize(type))) #define va_end(vaptr)