how does printf handle an unknown number of arguments

Discussion in 'C Programming' started by InuY4sha, Feb 5, 2009.

  1. InuY4sha

    InuY4sha Guest

    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
    InuY4sha, Feb 5, 2009
    #1
    1. Advertising

  2. InuY4sha <> writes:

    > 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!

    --
    Ben.
    Ben Bacarisse, Feb 5, 2009
    #2
    1. Advertising

  3. InuY4sha

    InuY4sha Guest

    On 5 Feb, 16:38, Ben Bacarisse <> wrote:
    > InuY4sha <> writes:
    > > 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!
    >
    > --
    > Ben.


    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
    InuY4sha, Feb 5, 2009
    #3
  4. InuY4sha

    jameskuyper Guest

    InuY4sha wrote:
    > On 5 Feb, 16:38, Ben Bacarisse <> wrote:
    > > InuY4sha <> writes:
    > > > 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.
    jameskuyper, Feb 5, 2009
    #4
  5. InuY4sha <> writes:

    <snip>
    > 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

    --
    Ben.
    Ben Bacarisse, Feb 6, 2009
    #5
  6. InuY4sha

    Guest

    On Feb 5, 9:29 pm, InuY4sha <> wrote:
    > On 5 Feb, 16:38, Ben Bacarisse <> wrote:
    >
    >
    >
    >
    >
    > > InuY4sha <> writes:
    > > > 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!

    >
    > > --
    > > Ben.

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

    -
    , Feb 6, 2009
    #6
  7. On 6 Feb 2009 at 6:05, Han from China wrote:
    > 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.
    Antoninus Twink, Feb 6, 2009
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lambda
    Replies:
    2
    Views:
    334
    Lambda
    Jul 3, 2008
  2. Replies:
    3
    Views:
    800
  3. srdgame
    Replies:
    5
    Views:
    475
    srdgame
    Mar 6, 2009
  4. Vincent Arnoux
    Replies:
    1
    Views:
    230
    Arnaud Bergeron
    Aug 11, 2006
  5. oldyork90
    Replies:
    10
    Views:
    334
    Jorge
    Sep 27, 2008
Loading...

Share This Page