variable number of arguments

T

The Directive

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?
 
B

Ben Pfaff

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?

You can't. trace() has to know the types of the arguments, or be
able to figure them out.
 
D

DomiPi

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
 
D

DomiPi

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

DomiPi said:
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
 
K

Keith Thompson

DomiPi said:
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

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.
 
T

The Directive

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
 
A

Arthur J. O'Dwyer

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?

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
 
K

Keith Thompson

Arthur J. O'Dwyer said:
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

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).
 
B

Ben Pfaff

Keith Thompson said:
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).

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;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top