tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: must use gcc builtin?

On Tue, Feb 21, 2012 at 11:29:20PM -0500, James K. Lowden wrote:
> >From /usr/include/machine/ansi.h:
> #ifdef __GNUC__
> #define _BSD_VA_LIST_    __builtin_va_list /* GCC built-in type */
> #else
> #define _BSD_VA_LIST_    char *    /* XXXfvdl should be ok? */ 
> #endif
> How  to avoid using gcc's builtin va_list when compiling with gcc?  
> Just for fun, I thought I'd try compiling Gary Capell's "wily"
> editor. The code is from 2006, hardly ancient.  Its library manipulates
> a va_list as pointer using assignment and subtraction.  AFAICT the
> above code makes that impossible.  The compiler certainly doesn't like
> it.  
>       return ap - (va_list)o;
>       ../../libplan9c/doprint.c:369: error: cast specifies array type

That code is very, very broken doing things like that just isn't allowed.
The fact that the code isn't ancient doesn't mean is is well written.

For architectures that pass argumets to varargs functions is registers
and use FP registers for FP values and ALU registers for ints and ptrs
'va_list' has to be a compound that remembers which values have been
used (note that the standard requires the values to be used in sequence).

However the va_list needs to be passable (efficiently) to functions like
vprintf(). To do this it sometimes defined as an array with one member
- so the definition allocates memory, but the function call passes
the address.

On i386 the calling convention just stacks all the args, so only a simple
pointer is needed. Microsofts amd64 calling convention requires space
be left to allow a called function to save the register args adjacent
to the stacked args - and I suspect varargs functions amke use of it.

However that isn't true of amd64 for all unix systems, nor ppc,
and I'm not 100% sure about sparc.

So if you want varargs, you have to use the compiler builtins.


David Laight:

Home | Main Index | Thread Index | Old Index