Using variadic functions within variadic functions

Discussion in 'C Programming' started by pinkfloydhomer@gmail.com, Feb 17, 2006.

  1. Guest

    Can I use printf inside a variadic function that I am writing?

    Like:

    void print(const char * format,...)
    {
    va_list va;
    va_start(va, format);
    char buffer[64*1024]; // yeah, I know...
    vsprintf(buffer, format, va);
    va_end(va);
    printf("--- %s ---", buffer);
    }

    I know the example is degenerate, but is it allowed, that is, does it
    have welldefined behavior?

    I would imagine that printf itself would also have need for the
    va_list, va_start etc. mechanism.

    /David
     
    , Feb 17, 2006
    #1
    1. Advertising

  2. wrote:
    > Can I use printf inside a variadic function that I am writing?
    >
    > Like:
    >
    > void print(const char * format,...)
    > {
    > va_list va;
    > va_start(va, format);
    > char buffer[64*1024]; // yeah, I know...
    > vsprintf(buffer, format, va);
    > va_end(va);
    > printf("--- %s ---", buffer);
    > }
    >
    > I know the example is degenerate, but is it allowed, that is, does it
    > have welldefined behavior?


    If 'buffer' contains a string, printf("--- %s ---", buffer);
    is ok, and legal. No magic tricks here, and this has nothing to
    do with varargs.
     
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Feb 17, 2006
    #2
    1. Advertising

  3. On 17 Feb 2006 01:45:37 -0800, ""
    <> wrote:

    > Can I use printf inside a variadic function that I am writing?
    >

    Yes. As long as you declare it correctly, by #include'ing <stdio.h>,
    as you must for _any_ call to it.

    > Like:
    >
    > void print(const char * format,...)
    > {
    > va_list va;
    > va_start(va, format);
    > char buffer[64*1024]; // yeah, I know...
    > vsprintf(buffer, format, va);
    > va_end(va);
    > printf("--- %s ---", buffer);
    > }
    >
    > I know the example is degenerate, but is it allowed, that is, does it
    > have welldefined behavior?
    >

    As long as a similar direct call to s[n]printf would, namely: you
    don't overflow buffer, a risk you already alluded to, and could
    protect against in C99 by using vsnprintf; and the data arguments you
    receive and pass on using va correctly match the format specifiers.
    (And don't overlap, but nothing validly provided by the caller can
    overlap your 'auto' buffer.) And you don't overflow the stack.

    > I would imagine that printf itself would also have need for the
    > va_list, va_start etc. mechanism.
    >

    No problem; varargs works separately for each vararg function. You can
    have vararg call vararg, vararg call nonvararg, vararg call nonvararg
    that calls vararg, etc., etc. The only thing you can't do is pass your
    own varargs on to another routine _as varargs_; instead you pass the
    entire list (or a suffix of it) as a va_list -- as you correctly do.

    The other thing to be careful of is that you can't pass 'your' va_list
    to a function that uses it to access the arguments (like vs[n]printf
    usually) _and_ use that same va_list to access the arguments yourself,
    because it is unspecified whether va_list is an array 'by reference'
    type or not. In C99 you can use va_copy to handle this. Or, even in
    C89, you can start, use and end two va_list objects explicitly; or one
    object with distinct (non-overlapping) ranges.

    Oh, and to be super-picky: your 64*1024 is nominally done in 'int'
    arithmetic, which is allowed to be only 1+15 bits and could overflow.
    In practice this will always be done at compile time and should be at
    least diagnosed, but is not strictly required to be. Moreover, 65536
    chars is greater than the minimum object size that must be supported,
    even (very slightly) in C99, and exceeding a resource limit isn't
    required to be diagnosed, although compile-time cases should be.

    And finally, it is implementation-dependent whether the last line of a
    text stream (which stdout is) must end in a newline. Your function by
    itself is valid, but if used in a program that does not subsequently
    output a newline on such a system it won't work as desired.

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Feb 27, 2006
    #3
    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. Loony

    variadic functions

    Loony, Sep 12, 2003, in forum: C++
    Replies:
    2
    Views:
    367
    Kevin Goodsell
    Sep 12, 2003
  2. Loony
    Replies:
    3
    Views:
    532
    Ron Natalie
    Sep 19, 2003
  3. Colin Walters
    Replies:
    2
    Views:
    528
    Ben Pfaff
    Feb 13, 2004
  4. Ross A. Finlayson
    Replies:
    19
    Views:
    610
    Keith Thompson
    Mar 10, 2005
  5. Replies:
    5
    Views:
    370
Loading...

Share This Page