Path: utzoo!attcan!uunet!mcvax!hp4nl!kunivv1!phoibos!ge From: ge@phoibos.UUCP (Ge Weijers) Newsgroups: comp.lang.c Subject: Re: Passing variable #of args Summary: portability of var. arg# Message-ID: <517@phoibos.UUCP> Date: 23 Jan 89 12:22:45 GMT References: <470@marob.MASA.COM> Organization: University of Nijmegen, The Netherlands. Lines: 34 In article <470@marob.MASA.COM>, daveh@marob.MASA.COM (Dave Hammond) writes: > I was surprised to see the following in a "GNU-something" source file: > > lprintf(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,10) > char *fmt; > { > char buf[BUFSIZ]; > sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,10) > ... > } > > Given the availability of varargs, is this style still acceptable and, > more importantly, is it portable? > > -- > Dave Hammond > ...!uunet!masa.com!{marob,dsix2}!daveh This is NOT portable. Some compilers use strange calling conventions which will cause this example to break. An example: The Turbo C compiler for the Atari ST (sold in Europe) uses registers to pass arguments. The calling convention is the following (except for details, I'm producing this from memory): The first 3 scalar (int, long, char etc.) variables are passed in registers D0-D2, and the first 2 pointer variables in A0-A1. The call f(3,&var) and f(&var,3) will yield the same code. The above example breaks. It is possible to use the ANSI variable argument passing, because the compiler does not pass arguments in registers that correspond to the ... in an ANSI prototype (line lprintf(char *format, ...)) You'd be better off using or , then it is at least obvious where you have to change a program.