Passing Arguments In C

Rodent Of Unusual Size cquenel at polyslo.CalPoly.EDU
Mon Sep 19 05:22:38 AEST 1988


In article <2232 at ssc-vax.UUCP> dmg at ssc-vax.UUCP (David Geary) writes:
>
>I teach an Advanced C class, and am showing my students how to write variadic
>functions.  I want to make sure that what I'm telling them is correct, and 
>also want to prepared to answer the questions in the above paragraph.  
>Any help, questions, comments, etc. are greatly appreciated.
>Thanx

I saw another reply that dealt with stacks and some basics, but
I thought I could add a little more.  I'm not a full-fledged, compiler
weenie, but I did work on one for a while.

I recently had to come up with an implementation of varargs for a 
compiler for a new architecture, and it was a pain.

The compiler is free to decide where/when/if to stick any of the following
on the stack : parameters, stack pointer, frame pointer, return value.
In general either the stack or frame pointer must be saved on the
stack along with the return value (which NOT the address of the routine, 
by the way, but the address of the instruction following the call, this
is where execution of the interrupted routine will continue) must be saved
on the stack. Debuggers work more easily and better if they can look back
on the stack and see ALL the parameters and both the stack and frame
pointers, and the return address, but many compilers do away with some
of this to make the code execute faster.

Perhaps the most common variation to the standard "dump everything
on the stack" approach is to pass the first X parameters in registers.

This is what I primarily wanted to tell you about.

All a C programmer REALLY needs to know about is that the VARARGS macros
should work as documented.  Compiler writers are the ones that have to deal
with the headaches.  The problems stem from the fact that the compiler 
cannot depend on having a "prototype", (that is, a definition of the
types of parameters passed to a routine) when it generates code for the 
procedure call.  This necessitates the following scheme:
	Call all procedures as if they WERE NOT varargs routines (that
is, pass X parameters in registers) and let the varargs routine deal
with it as it sees fit, BUT reserve stack space on the stack for the
parameters you didn't save (the reason for this will be made clear).

When the compiler compiles a varargs routine, the first code generated dumps
the first parameters from the incoming registers onto the stack, into
the space reserved for them.  This gives a nice consecutive string
of parameters in memory for varargs to step through.

This is necessary because the common usage of VARARGS allows an
abstract parameter list to be /passed to other functions/.  The only
practical method for doing this is with a pointer, and for that the
paramaters need to be on the stack.

NOTE: This scheme allows all the varargs macros to be implemented without 
function calls, as simple pointer expressions that increment/dereference
a pointer.  It is also possible for a compiler to implement varargs
as a procedure call to a routine that "figures out" a more complicated
scheme.

Also note.  This scheme requires that the X registers used for
parameters BE TREATED AS IF THEY WERE WORDS OF MEMORY ON THE STACK.
Even if the first 4 bytes of a structure have to shoved in a register,
and the rest put on the stack.

Basically, passing structures by value (NOT passing a pointer)
f*cks you over real good.

In theory it is possible to do whatever you want with the varargs
macros because you tell them the type of the thing you want, but in 
practice the only thing you can do with a type is take it's size,
and an 8 byte double precision value the compiler would like to
stick in a register, and an 8 byte struct the compiler would like
to shove on the stack where it shoves all the other structs.

Anyway, I digress, I hope that gives more than enough information
than you wanted to know about variadic functions in C

To quote someone who IS a compiler weenie (whose name I forget
for the moment [Mark, can you tell me ?]) :

"When varargs strikes there are no survivors."

:-)

-------------------------------------------------------------------------------
| Chris Quenelle            | Smart Mailers -> cquenel at polyslo.CalPoly.EDU    |
| Computer Systems Lab      | Dumb Mailers  -> !ucbvax!voder!polyslo!cquenel  |
| Cal Poly State Univ.      |-------------------------------------------------|
| San Luis Obispo, CA 93407 | /earth is 98% full, please delete anyone you can|
-------------------------------------------------------------------------------



More information about the Comp.lang.c mailing list