[comp.lang.c] Grabbing "n" arguments in a function

peter@brontolo.sublink.ORG (Network administrator) (04/29/90)

In article <297@ndla.UUCP>, platt@ndla.UUCP (Daniel E. Platt) writes:
] In article <559@dplace.UUCP>, djl@dplace.UUCP (Dave Lampe) writes:
] > rick@tmiuv0.uucp writes:
] > 
] > >What's the most portable way for a function to receive an arbitrary list of
] > >arguments?  The function must receive "n" arguments, all of which are char.
] > >pointers:
] > 
] > >    char *weirdfunc(char *arg1, char *arg2, ... char *argn) {
] > 
] ...In your case 
] you'ld continue popping the things from the stack until you got a NULL.

Dan's method to get arguments from the function's stack is very usefull,
and is worth ok on every OS and C compiler I have tried, exept for the
DEC's RISC one.

Does anybody out there know how to do the same variable argument call
(WITHOUT "varargs", please! [it doesn't work, too!!!!!]) under MIPS
RISC workstation (or DEC's one) ?????????
Thank you
Peter


-- 
Peter Komanns ************- SINDATA srl -*****************
Via Rovereto 17            | BANG ..!rutgers!deejay!yachaya!brontolo!peter
20059 Vimercate MI ITALY   | SUBLINK peter@brontolo
(voice) +39-39-6083733       (fax)   +39-39-6083957 

uma@slug..austin.ibm.com (05/01/90)

In article <744@tmiuv0.uucp> rick@tmiuv0.uucp writes:
>Ok, I know this may be a stupid question, but I'll brave the arrows and
>missiles hurled in my direction...
>
>What's the most portable way for a function to receive an arbitrary list of
>arguments?  The function must receive "n" arguments, all of which are char.
>pointers:
>

I think the most portable way to achieve this is to use "varargs" feature
as provided by the libc.a(on UNIX, I don't know about other OS). See
/usr/include/varargs.h on UNIX System V any release. and also
K&R C book describes how to use it too( 2nd edition of K&R C book pages 
155-159).

>  .-------------------------------------------------------------------------.
> / [- O] Rick Stevens (All opinions are mine. Everyone ignores them anyway.) \
>|    ?   +--------------------------------------------------------------------|
>|    V   | uunet!zardoz!tmiuv0!rick             (<-- Work (ugh!))             |
>|--------+ uunet!zardoz!xyclone!sysop           (<-- Home Unix (better!))     |
>|  uunet!perigrine!ccicpg!conexch!amoeba2!rps2  (<-- Home Amiga (Best!!)      |
> \ 75006.1355@compuserve.com (CIS: 75006,1355)  (<-- CI$)                    /
>  `-------------------------------------------------------------------------'
>"A day without sunshine is like..............night!"

===============================================================================
Uma S. Pandey (contractor at IBM)     	Disc:  "Any opinions are mine"
Internal:uma@slug.austin.ibm.com   VNET: sc10333 at ausvmq  
External: uunet!cs.utexas.edu!ibmaus!auschs!slug.austin.ibm.com!uma
===============================================================================
===============================================================================
Uma S. Pandey (contractor at IBM)     	Disc:  "Any opinions are mine"
Internal:uma@slug.austin.ibm.com   VNET: sc10333 at ausvmq  T/L 793-4078.
External: uunet!cs.utexas.edu!ibmaus!auschs!slug.austin.ibm.com!uma

meissner@osf.org (Michael Meissner) (05/03/90)

In article <347@brontolo.sublink.ORG> peter@brontolo.sublink.ORG
(Network administrator) writes:

| In article <297@ndla.UUCP>, platt@ndla.UUCP (Daniel E. Platt) writes:
| ] In article <559@dplace.UUCP>, djl@dplace.UUCP (Dave Lampe) writes:
| ] > rick@tmiuv0.uucp writes:
| ] > 
| ] > >What's the most portable way for a function to receive an arbitrary list of
| ] > >arguments?  The function must receive "n" arguments, all of which are char.
| ] > >pointers:
| ] > 
| ] > >    char *weirdfunc(char *arg1, char *arg2, ... char *argn) {
| ] > 
| ] ...In your case 
| ] you'ld continue popping the things from the stack until you got a NULL.
| 
| Dan's method to get arguments from the function's stack is very usefull,
| and is worth ok on every OS and C compiler I have tried, exept for the
| DEC's RISC one.
| 
| Does anybody out there know how to do the same variable argument call
| (WITHOUT "varargs", please! [it doesn't work, too!!!!!]) under MIPS
| RISC workstation (or DEC's one) ?????????
| Thank you

By the way, it probably won't work for any other implementation that
passes arguments in registers (including most RISC processors, like
the 88k).  For machines that pass things in registers, the compiler
has to store any registers normally used for passing arguments for
varargs type arguments.  For MIPS-based processors, this means storing
$4-$7 in the appropriate locations on the stack (which the caller must
allocate).  MIPS machines have another fly in the ointment, in that if
the first argument to a function is floating point, it is passed in a
floating point register, and not an integer register, which totally
messes up any varargs function with a floating point number as the
first argument.  For the 88k, it is more complicated, since structures
are passed on the stack (unlike MIPS), so you can't arbitrarily store
the registers in their 'home' location, so you save r2-r7 in a special
8 word area, and use a state variable within the varargs routine to
index through the special 8 word area, or the normal stack argument
area.  Finally, there are machines like the Data General MV, whose
stack grows backwards to most other machines in the universe.

There are good reasons why the varargs/stdarg layer is necessary, and
if your problem can't use varargs/stdarg, you would be well advised to
take some different tack.

--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA

Catproof is an oxymoron, Childproof is nearly so

andre@targon.UUCP (andre) (05/07/90)

In article <1990Apr22.010146.5001@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
]In article <744@tmiuv0.uucp> rick@tmiuv0.uucp writes:
]>What's the most portable way for a function to receive an arbitrary list of
]>arguments? ...
]
]The *only* maximally portable way to do this is to use the <stdargs.h>
]facility in ANSI C.  Using <varargs.h>, found in many current systems,
	[ things you should not do ]

There is one more method though,
accept an 'argv' like array as the argument to your function.
as in,

int number_args (a)
char **a;
{
	int n;

	for (n = 0 ; a[n] ; n++)
	    ;

	return n;
}

And if you malloc and realloc the char * array, this size can
change at runtime, while the varargs approach is fixed at compile time.

-- 
The mail|    AAA         DDDD  It's not the kill, but the thrill of the chase.
demon...|   AA AAvv   vvDD  DD        Ketchup is a vegetable.
hits!.@&|  AAAAAAAvv vvDD  DD                    {nixbur|nixtor}!adalen.via
--more--| AAA   AAAvvvDDDDDD    Andre van Dalen, uunet!hp4nl!targon!andre