Connecting Tech Pros Worldwide Forums | Help | Site Map

variable number of arguments

The Directive
Guest
 
Posts: n/a
#1: Nov 14 '05
I read the C FAQ question on passing a variable number of arguments,
but it didn't help. The example assumes all arguments are of the same
type.

I want to create a function "trace" that can be used like this:

trace( "Err", errtType, lineNum, NULL) /* where errType is char* and
lineNum is
an int */

trace("Err", lineNum, NULL);

trace( lineNum, "Err", funcName, NULL) /* where funName is char * */

The problem is that I don't know the order and the variable types of
the arguments passed.

How can I implement trace?

Ben Pfaff
Guest
 
Posts: n/a
#2: Nov 14 '05

re: variable number of arguments


the_directive@hotmail.com (The Directive) writes:
[color=blue]
> I want to create a function "trace" that can be used like this:
>
> trace( "Err", errtType, lineNum, NULL) /* where errType is char* and
> lineNum is
> an int */
>
> trace("Err", lineNum, NULL);
>
> trace( lineNum, "Err", funcName, NULL) /* where funName is char * */
>
> The problem is that I don't know the order and the variable types of
> the arguments passed.
>
> How can I implement trace?[/color]

You can't. trace() has to know the types of the arguments, or be
able to figure them out.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
DomiPi
Guest
 
Posts: n/a
#3: Nov 14 '05

re: variable number of arguments


Hi
I already wrote a function of the same type. But I believe that it is
necessary to have at least a parameter which will describe the following.
Like does it printf, you could have: trace(char format,...);
with for example:
trace("Err Line:%d Type:%c File name:%s,__LINE__,mytype,__FILE__);
If you want, I can send my source
Dominique

"The Directive" <the_directive@hotmail.com> a écrit dans le message de
news:8477bc58.0401111157.6906a7bb@posting.google.c om...[color=blue]
> I read the C FAQ question on passing a variable number of arguments,
> but it didn't help. The example assumes all arguments are of the same
> type.
>
> I want to create a function "trace" that can be used like this:
>
> trace( "Err", errtType, lineNum, NULL) /* where errType is char* and
> lineNum is
> an int */
>
> trace("Err", lineNum, NULL);
>
> trace( lineNum, "Err", funcName, NULL) /* where funName is char * */
>
> The problem is that I don't know the order and the variable types of
> the arguments passed.
>
> How can I implement trace?[/color]


DomiPi
Guest
 
Posts: n/a
#4: Nov 14 '05

re: variable number of arguments


Oups error:
trace(char *format, ...);

"DomiPi" <akuj0006@tiscali.be> a écrit dans le message de
news:btsbp4$kbv$1@news.worldonline.be...[color=blue]
> Hi
> I already wrote a function of the same type. But I believe that it is
> necessary to have at least a parameter which will describe the following.
> Like does it printf, you could have: trace(char format,...);
> with for example:
> trace("Err Line:%d Type:%c File name:%s,__LINE__,mytype,__FILE__);
> If you want, I can send my source
> Dominique
>
> "The Directive" <the_directive@hotmail.com> a écrit dans le message de
> news:8477bc58.0401111157.6906a7bb@posting.google.c om...[color=green]
> > I read the C FAQ question on passing a variable number of arguments,
> > but it didn't help. The example assumes all arguments are of the same
> > type.
> >
> > I want to create a function "trace" that can be used like this:
> >
> > trace( "Err", errtType, lineNum, NULL) /* where errType is char* and
> > lineNum is
> > an int */
> >
> > trace("Err", lineNum, NULL);
> >
> > trace( lineNum, "Err", funcName, NULL) /* where funName is char * */
> >
> > The problem is that I don't know the order and the variable types of
> > the arguments passed.
> >
> > How can I implement trace?[/color]
>
>[/color]


Peter Pichler
Guest
 
Posts: n/a
#5: Nov 14 '05

re: variable number of arguments


"DomiPi" <akuj0006@tiscali.be> wrote in message
news:btscec$l47$1@news.worldonline.be...[color=blue]
> Oups error:
> trace(char *format, ...);[/color]

Oups (sic) error: top-post.

<rest snipped for clarity>

Peter


CBFalconer
Guest
 
Posts: n/a
#6: Nov 14 '05

re: variable number of arguments


Peter Pichler wrote:[color=blue]
> "DomiPi" <akuj0006@tiscali.be> wrote in message
>[color=green]
> > Oups error:
> > trace(char *format, ...);[/color]
>
> Oups (sic) error: top-post.
>
> <rest snipped for clarity>[/color]

A fine riposte.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


Keith Thompson
Guest
 
Posts: n/a
#7: Nov 14 '05

re: variable number of arguments


"DomiPi" <akuj0006@tiscali.be> writes:[color=blue]
> I already wrote a function of the same type. But I believe that it is
> necessary to have at least a parameter which will describe the following.
> Like does it printf, you could have: trace(char format,...);
> with for example:
> trace("Err Line:%d Type:%c File name:%s,__LINE__,mytype,__FILE__);
> If you want, I can send my source[/color]

There are a number of ways that a function taking a variable number of
arguments can be told the number and type of the arguments. printf's
format string is probably the most common. If all the arguments
(after the initial one(s)) are of the same type, a sentinel value,
such as a null pointer, can be used to mark the end of the list.

Another approach (one that I've never actually seen) is for every
other argument to specify the type of the following one:

foo('i', 42,
'd', 123.4,
's', "hello");

Whatever method is used, it's the caller's responsibility to make sure
everything is consistent. If you pass a pointer where the function
looks for an int, you're not likely to get any help from the compiler.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
The Directive
Guest
 
Posts: n/a
#8: Nov 14 '05

re: variable number of arguments


From everyone's responses, I conclude that there's no easy, clean way
to pass a variable number of arguments with variable unknown types in
C. Correct? That information must be passed as another argument. What
was the reasoning for the C language designers to implement it this
way? Is it a weakness of the language?

--The Directive

Keith Thompson <kst-u@mib.org> wrote in message news:<lnhdz26rzt.fsf@nuthaus.mib.org>...[color=blue]
> "DomiPi" <akuj0006@tiscali.be> writes:[color=green]
> > I already wrote a function of the same type. But I believe that it is
> > necessary to have at least a parameter which will describe the following.
> > Like does it printf, you could have: trace(char format,...);
> > with for example:
> > trace("Err Line:%d Type:%c File name:%s,__LINE__,mytype,__FILE__);
> > If you want, I can send my source[/color]
>
> There are a number of ways that a function taking a variable number of
> arguments can be told the number and type of the arguments. printf's
> format string is probably the most common. If all the arguments
> (after the initial one(s)) are of the same type, a sentinel value,
> such as a null pointer, can be used to mark the end of the list.
>
> Another approach (one that I've never actually seen) is for every
> other argument to specify the type of the following one:
>
> foo('i', 42,
> 'd', 123.4,
> 's', "hello");
>
> Whatever method is used, it's the caller's responsibility to make sure
> everything is consistent. If you pass a pointer where the function
> looks for an int, you're not likely to get any help from the compiler.[/color]
Arthur J. O'Dwyer
Guest
 
Posts: n/a
#9: Nov 14 '05

re: variable number of arguments



On Mon, 11 Jan 2004, The Directive wrote:[color=blue]
>
> From everyone's responses, I conclude that there's no easy, clean way
> to pass a variable number of arguments with variable unknown types in
> C. Correct? That information must be passed as another argument. What
> was the reasoning for the C language designers to implement it this
> way? Is it a weakness of the language?[/color]

Please snip the part of the previous message to which you're not
responding. And don't top-post. http://www.google.com/search?q=top+post

Now, as to your question: Correct. That information (about types)
must be passed as another argument, or built into the structure of the
arguments in the first place. (For example, you could pass a list of
positive integers to a function, and end the list with -1. The
function would know to stop reading arguments when it hit that -1.)
The C language was designed this way because it's incredibly easy
to code, and it's pretty fast [with relatively naive optimization], too,
compared to other ways. Compare the C model to the "Pascal" model,
which can't support variadic functions at all. Search Google for
"argument passing conventions," and then try comp.compilers,
comp.programming, or a similar group if you have implementation
questions.
It's a weakness of the language when compared to languages that
provide more functionality (such as a count of arguments magically
supplied by the compiler); but off the top of my head, the only
language I know that does better is Matlab, and it's got its own
weaknesses. :) It's a trade-off between ease of implementation, power,
and user-friendliness. Since most users don't define functions where
they don't know what they're going to be passing as arguments, it
probably didn't seem a big deal when C was being standardized.

Historical note: I seem to recall that in pre-1989 days, there
was no [de facto] language support for variadic functions at all.
printf and scanf worked by magic; the user was not generally able to
write his own printf-alikes. Do I recall correctly?

-Arthur

Keith Thompson
Guest
 
Posts: n/a
#10: Nov 14 '05

re: variable number of arguments


"Arthur J. O'Dwyer" <ajo@nospam.andrew.cmu.edu> writes:
[...][color=blue]
> Historical note: I seem to recall that in pre-1989 days, there
> was no [de facto] language support for variadic functions at all.
> printf and scanf worked by magic; the user was not generally able to
> write his own printf-alikes. Do I recall correctly?
>
> -Arthur[/color]

There was a <varargs.h> header that predated the current <stdarg.h>
header. Since <stdarg.h> is in the 1989 ANSI standard, <varargs.h>
must have existed before 1989.

But I think that there was a time, before <varargs.h> was invented,
when printf and scanf worked by magic (e.g., by explicitly computing
stack offsets for successive arguments).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Ben Pfaff
Guest
 
Posts: n/a
#11: Nov 14 '05

re: variable number of arguments


Keith Thompson <kst-u@mib.org> writes:
[color=blue]
> There was a <varargs.h> header that predated the current <stdarg.h>
> header. Since <stdarg.h> is in the 1989 ANSI standard, <varargs.h>
> must have existed before 1989.
>
> But I think that there was a time, before <varargs.h> was invented,
> when printf and scanf worked by magic (e.g., by explicitly computing
> stack offsets for successive arguments).[/color]

Here's the printf() from the Lions Book circa 1976. All typos
are mine.

/*
* Scaled down version of C Library printf.
* Only %s %l %d (==%l) %o are recognized.
* Used to print diagnostic information
* directly on console tty.
* Since it is not interrupt driven,
* all system activities are pretty much
* suspended.
* Printf should not be used for chit-chat.
*/
printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9,xa,xb,xc)
char fmt[];
{
register char *s;
register *adx, c;

adx = &x1;
loop:
while((c = *fmt++) != '%') {
if(c == '\0')
return;
putchar(c);
}
c = *fmt++;
if(c == 'd' || c == 'l' || c == 'o')
printn(*adx, c=='o'? 8: 10);
if(c == 's') {
s = *adx;
while(c == *s++)
puthcar(c);
}
adx++;
goto loop;
}
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Closed Thread