how does printf handle an unknown number of arguments

I

InuY4sha

I'd like a macro or something to do something like the following :
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123
I mean how do I handle an arbitrary number of arguments in C?
A short example would be WOW! :D
Thanks list
 
B

Ben Bacarisse

InuY4sha said:
I'd like a macro or something to do something like the following

The devil is often in the detail. Questions that relate to "something
like" what you need are often a problem down the line...
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123;
I mean how do I handle an arbitrary number of arguments in C?

Ah, that is simpler. You declare (and later define) your function
with ... after the arguments you know about (and there must be at
least one of those):

int my_printf(const char *fmt, ...);

but this is only where the problems start! In C, you can't enquire
about the types of these as yet unknown arguments, so something must
allow your function find out. Maybe they are all the same, maybe
there is something like a format string that implies the types... As
I say, the devil is in the detail. An idea of what you really need to
do would help.

Macros, can be used to a very limited extent. Again, I don't want to
explain all the possibilities because the chances are they won't apply
in your case!
 
I

InuY4sha

InuY4sha said:
I'd like a macro or something to do something like the following

The devil is often in the detail. Questions that relate to "something
like" what you need are often a problem down the line...
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123;
I mean how do I handle an arbitrary number of arguments in C?

Ah, that is simpler. You declare (and later define) your function
with ... after the arguments you know about (and there must be at
least one of those):

int my_printf(const char *fmt, ...);

but this is only where the problems start! In C, you can't enquire
about the types of these as yet unknown arguments, so something must
allow your function find out. Maybe they are all the same, maybe
there is something like a format string that implies the types... As
I say, the devil is in the detail. An idea of what you really need to
do would help.

Macros, can be used to a very limited extent. Again, I don't want to
explain all the possibilities because the chances are they won't apply
in your case!

The point is
1) I *need* a dbg_print function that exploit printf functionalities
(to be free to play with different behaviors in the future).. but this
could be solved with something like

#define dbg_print(x) (printf(x))

2) I'm curious about printf.. and I think that knowing the underlaying
theory before to dig into the code could save a lot of troubles...

So let's make a simple case to detail the required functionalities,
I'd like all of the arguments to be always treated as char arrays.

Btw how would I address those "void*" arguments inside the function?

Thanks for your detailed answer for now! :D
 
J

jameskuyper

InuY4sha said:
InuY4sha said:
I'd like a macro or something to do something like the following ....
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123;
I mean how do I handle an arbitrary number of arguments in C?

Ah, that is simpler. You declare (and later define) your function
with ... after the arguments you know about (and there must be at
least one of those):

int my_printf(const char *fmt, ...);
.....
The point is
1) I *need* a dbg_print function that exploit printf functionalities
(to be free to play with different behaviors in the future).. but this
could be solved with something like

#define dbg_print(x) (printf(x))

2) I'm curious about printf.. and I think that knowing the underlaying
theory before to dig into the code could save a lot of troubles...

Before standardization, the printf() function was "magic" - it did
things that no user-written C program could do, at least not in any
portable fashion. When C was first standardized, the <stdarg.h> header
was added, allowing anybody to write a routine taking a variable
number of arguments.

The function you want to implement has to parse a format string. The
easiest way to handle this would be to write a wrapper for vsprintf(),
but you wouldn't learn much about how variable arguments are handled
if you used that approach. It also needs to return a pointer to a
piece of memory which you can safely discard (at least, your example
code discards it, making it impossible to free() it if the memory were
allocated with malloc()). In order to provide a very simple example of
how to use <stdarg.h>, I'll ignore both of those features and write a
much simpler function, which takes a variable list of int arguments
and writes them to an array.

foo.h:
void foo(int, int *, ...);

foo.c:
#include <stdarg.h>
#include "foo.h"

void foo(int n, int *out, ...)
{
va_list ap;

if(!out)
return;

// out is the last field before the ... at
// the end of the function declaration.
va_start(ap, out);
while(n-- > 0)
*out++ = va_arg(ap, int);
va_end(ap);
}

A key thing to notice is that foo() must be able to figure out by some
method how many argument it expects to receive (that's what n is for),
and what types they have (in this case, its expecting exclusively
'int' arguments. The <stdarg.h> routines do not, themselves, provide
any way of determining those answers.
 
B

Ben Bacarisse

The point is
1) I *need* a dbg_print function that exploit printf functionalities
(to be free to play with different behaviors in the future).. but this
could be solved with something like

#define dbg_print(x) (printf(x))

2) I'm curious about printf.. and I think that knowing the underlaying
theory before to dig into the code could save a lot of troubles...

I'll add to James' reply that you should read all of section 15 of the
C FAQ: http://c-faq.com/varargs/index.html
 
B

baeuar

The devil is often in the detail.  Questions that relate to "something
like" what you need are often a problem down the line...
int a=1,b=2,c=3;
char c[4];
memcpy(c,foo("%i%i%i",a,b,c),4)
printf("%s\n",c) = 123;
I mean how do I handle an arbitrary number of arguments in C?
Ah, that is simpler.  You declare (and later define) your function
with ... after the arguments you know about (and there must be at
least one of those):
  int my_printf(const char *fmt, ...);
but this is only where the problems start!  In C, you can't enquire
about the types of these as yet unknown arguments, so something must
allow your function find out.  Maybe they are all the same, maybe
there is something like a format string that implies the types...  As
I say, the devil is in the detail.  An idea of what you really need to
do would help.
Macros, can be used to a very limited extent.  Again, I don't want to
explain all the possibilities because the chances are they won't apply
in your case!

The point is
1) I *need* a dbg_print function that exploit printf functionalities
(to be free to play with different behaviors in the future).. but this
could be solved with something like

#define dbg_print(x) (printf(x))

2) I'm curious about printf.. and I think that knowing the underlaying
theory before to dig into the code could save a lot of troubles...

So let's make a simple case to detail the required functionalities,
I'd like all of the arguments to be always treated as char arrays.

Btw how would I address those "void*" arguments inside the function?

Thanks for your detailed answer for now! :D- Hide quoted text -

- Show quoted text

refer to stdarg.h in ansi standard

-
 
A

Antoninus Twink

the scruffy-beard-and-creepy-pedophile-mugshot kind of C programmer
like many of our comp.lang.c regulars.

Ah, I see you've visited his website too then...

Superb explanation, by the way - the only thing I'd have added is a note
about the default promotions, which can be a slightly slippery point
when dealing with varargs functions.
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top