Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!aplcen!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!usc!ucsd!ucbvax!agate!tornado.Berkeley.EDU!dankg From: dankg@tornado.Berkeley.EDU (Dan KoGai) Newsgroups: comp.lang.c Subject: Re: passing variable arguments Message-ID: <1990Jun8.165259.8368@agate.berkeley.edu> Date: 8 Jun 90 16:52:59 GMT References: <353@ankh.ftl.fl.us> Sender: usenet@agate.berkeley.edu (USENET Administrator;;;;ZU44) Reply-To: dankg@tornado.Berkeley.EDU (Dan KoGai) Organization: ucb Lines: 53 In article <353@ankh.ftl.fl.us> chin@ankh.ftl.fl.us (Albert Chin) writes: >How does printf() work. I believe there is some way in C to obtain the >pointer to the argument list in a function. If so, printf() is pretty >simple. But how do you do this. Is it possible to get the number of >arguments in a printf() statement? On C convention, arguments are pushed to the stack right to left order before it jumps to the function. Since you can push as many arguments as your memory spec allows, it's quite possible, as you see on printf, to make variable argument functions on C. However, variable argument functions are somewhat kludgy on C: Bad news is that you have to explicity include the number of arguments somewhere in your argument and there's no other way of getting number of arguments: in printf() and scanf(), et al., It's number of '%'s in format and it might crash if you give wrong number of arguments. Also note there's no way you can tell the type of arguments in variable arg functions--printf() uses format to specify it and even though you feed wrong type args in printf() it uses argument type implied in format--it's a common mistake to pass int, instead of pointer to int in scanf(). On Ansi C, you can use macro package to write variable argument function. And variable argument is implied by "...". Here's simple example: #include /* multiple strcat */ char *mstrcat(int, nsrc, char *dst, char *src1, ...) /*... means more args to come */ { va_list srcs; /* va_list is typically void ** */ va_start(srcs, src1); /* now srcs = &src1 */ while(nsrc--){ /* repeat nsrc times */ strcat(dst, va_arg(char *, srcs)); /* va_arg(type, valist) returns *(type)valist then inclements valist */ } va_end(srcs) /* clears stack or do nothing: compiler dependent */ return dst; } You can get more details from K&R. The most important thing to remember is that in C you have to know how many number of what types of arguments are there. You C compiler will not take care of you. ---------------- ____ __ __ + Dan The "printf("%d", printf("d", printf.." Man ||__||__| + E-mail: dankg@ocf.berkeley.edu ____| ______ + Voice: +1 415-549-6111 | |__|__| + USnail: 1730 Laloma Berkeley, CA 94709 U.S.A |___ |__|__| + |____|____ + "What's the biggest U.S. export to Japan?" \_| | + "Bullshit. It makes the best fertilizer for their rice"