Creative uses for variable argument list functions

Discussion in 'C Programming' started by Spiros Bousbouras, Jul 30, 2007.

  1. Every time I've seen an example of a variable argument list
    function its functionality was to print formatted output. Does
    anyone have examples where the function is not some variation
    of printf ?
     
    Spiros Bousbouras, Jul 30, 2007
    #1
    1. Advertising

  2. Spiros Bousbouras said:

    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    What a curious question! Well, let's see...

    It's easy to come up with examples, of course - but rather harder to
    come up with examples that might actually be useful. For example, one
    might calculate a sum using 0 as a terminator (since 0 doesn't affect
    the sum, this is not unreasonable), but why bother? One might just as
    easily write a routine that sums the first n items in an array, which
    would be far more useful.

    I suspect that, if there is a good answer to your question, it might lie
    in the realms of expression-parsing or something along those lines.

    I look forward to reading other answers, hopefully from people who are
    thinking more creatively than me today.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jul 30, 2007
    #2
    1. Advertising

  3. In article <>,
    Richard Heathfield <> wrote:
    >Spiros Bousbouras said:
    >
    >> Every time I've seen an example of a variable argument list
    >> function its functionality was to print formatted output. Does
    >> anyone have examples where the function is not some variation
    >> of printf ?

    >
    >What a curious question! Well, let's see...
    >
    >It's easy to come up with examples, of course - but rather harder to
    >come up with examples that might actually be useful. For example, one
    >might calculate a sum using 0 as a terminator (since 0 doesn't affect
    >the sum, this is not unreasonable), but why bother? One might just as
    >easily write a routine that sums the first n items in an array, which
    >would be far more useful.
    >
    >I suspect that, if there is a good answer to your question, it might lie
    >in the realms of expression-parsing or something along those lines.
    >
    >I look forward to reading other answers, hopefully from people who are
    >thinking more creatively than me today.


    The one time I used this was to write a "max" function, that would
    return the maximum value from a list of numbers.
     
    Kenny McCormack, Jul 30, 2007
    #3
  4. Spiros Bousbouras wrote:
    >
    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    How about a version of strcat() that takes a list of strings, which
    could be called like this:

    StrCatList(MyBuffer,MyBufferLen,string1,string2,string3,NULL);

    Yes, one could use sprintf() for this, but strcat-like functionality
    is (most likely) more efficient.

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jul 30, 2007
    #4
  5. On Jul 30, 12:38 pm, Spiros Bousbouras <> wrote:
    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    I once wrote a variable argument string concatenation function that
    returned a new string consisting of a catenation of all the provided
    strings. The variable argument facility is useful is when you need to
    create a function that can operate on a variable number of items in
    which it would be inconvenient or impossible to supply the items as an
    array. Examples include the execl* functions in POSIX and functions
    that accept placeholders for a prepared statement in a SQL API.

    Robert Gamble
     
    Robert Gamble, Jul 30, 2007
    #5
  6. Kenneth Brody said:

    > Spiros Bousbouras wrote:
    >>
    >> Every time I've seen an example of a variable argument list
    >> function its functionality was to print formatted output. Does
    >> anyone have examples where the function is not some variation
    >> of printf ?

    >
    > How about a version of strcat() that takes a list of strings, which
    > could be called like this:
    >
    > StrCatList(MyBuffer,MyBufferLen,string1,string2,string3,NULL);
    >
    > Yes, one could use sprintf() for this, but strcat-like functionality
    > is (most likely) more efficient.


    Since it's my day for being dense, I suppose I might as well attract
    some flak for messing up the implementation:

    #include <stdarg.h>
    #include <stddef.h>

    int catstrlist(char *buf, size_t len, ...)
    {
    int rc = 1; /* insufficient memory */
    const char *arg = "";

    va_list ap = {0};

    va_start(ap, len);

    while(len > 1 && arg != NULL)
    {
    if(*arg == '\0')
    {
    arg = va_arg(ap, const char *);
    }
    else
    {
    *buf++ = *arg++;
    --len;
    }
    }
    *buf = '\0';
    if(arg == NULL)
    {
    rc = 0; /* all done successfully */
    }

    va_end(ap);
    return rc;
    }


    /* driver */
    #include <stdio.h>
    #include <string.h>

    int main(void)
    {
    int rc = 0;
    char target[32] = {0};

    rc = catstrlist(target,
    sizeof target,
    "Hello", "World", NULL);
    printf("Expected [HelloWorld], "
    "got [%s]: Expected 0, got %d\n", target, rc);

    memset(target, 0, sizeof target);
    rc = catstrlist(target,
    sizeof target,
    "Now", "Is", "The", "Hour", NULL);
    printf("Expected [NowIsTheHour], "
    "got [%s]: Expected 0, got %d\n", target, rc);

    memset(target, 0, sizeof target);
    rc = catstrlist(target,
    sizeof target,
    "WayTooManyInputCharacters",
    "In", "This", "Sequence", NULL);
    printf("Expected [WayTooManyInputCharactersInThis], "
    "got [%s]: Expected 1, got %d\n", target, rc);

    return 0;
    }

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jul 30, 2007
    #6
  7. "Spiros Bousbouras" <> wrote in message
    news:...
    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?
    >

    One example that comes to mind is on Unix/Linux using Xt functions
    such as XtVaSetValues( object, ..., NULL )
    where ...,NULL represents a NULL-terminated list of
    resource name/value pairs to set on the specified object.
    --
    Fred L. Kleinschmidt
    Boeing Associate Technical Fellow
    Aero Stability and Controls Computing
     
    Fred Kleinschmidt, Jul 30, 2007
    #7
  8. Spiros Bousbouras

    Eric Sosman Guest

    Kenneth Brody wrote On 07/30/07 13:33,:
    > Spiros Bousbouras wrote:
    >
    >>Every time I've seen an example of a variable argument list
    >>function its functionality was to print formatted output. Does
    >>anyone have examples where the function is not some variation
    >>of printf ?

    >
    >
    > How about a version of strcat() that takes a list of strings, which
    > could be called like this:
    >
    > StrCatList(MyBuffer,MyBufferLen,string1,string2,string3,NULL);


    Side-issue: Question 5.2 in the comp.lang.c Frequently
    Asked Questions (FAQ) list <http://www.c-faq.com/> explains
    why this is *not* the right way to call such a function.

    To the original point: The variable argument list is
    best avoided except when it's unavoidable, because it offers
    so many opportunities for error. The principal difficulty
    is that the compiler does not know your conventions for the
    arguments, and thus can't warn when you violate your own
    rules accidentally -- as above, for example. You get the
    dubious pleasure of having your code compile successfully
    and then chasing down the undefined behavior at leisure.

    That, I think, does a lot to explain the relative rarity
    of varargs. It's more or less unavoidable in I/O (where it
    gives you not only the ability to pass argument lists of
    varying lengths, but also of varying composition), but in
    other settings people usually try to make their interfaces
    less error-prone by finding ways to use fixed argument lists.

    --
     
    Eric Sosman, Jul 30, 2007
    #8
  9. Spiros Bousbouras

    dan Guest

    On Jul 30, 8:38 am, Spiros Bousbouras <> wrote:
    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    I got thinking the same thing recently. Can variable argument list
    functions be used to make a function able to handle int, long, or
    float, depending on what is passed? As a simple example, a MAX
    function, as someone else mentioned, that could deal with different
    number types.

    Is yes, would that be a good idea, or just better to write separate
    functions?

    Daniel Goldman
     
    dan, Jul 30, 2007
    #9
  10. In article <>,
    dan <> wrote:
    >I got thinking the same thing recently. Can variable argument list
    >functions be used to make a function able to handle int, long, or
    >float, depending on what is passed? As a simple example, a MAX
    >function, as someone else mentioned, that could deal with different
    >number types.


    Yes, but keep in mind that the mechanisms have no inherent way
    to find out what the type of the passed variable was, and so must
    be told (and so must hope that the teller didn't accidently
    misrepresent the types.) For example, you could have

    GenericOutputType MYMAX(argtypeindicator, ...)

    GenericOutputType perhaps being void* or a union type -- something
    allowing you to return different types depending on the inputs.
    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
     
    Walter Roberson, Jul 30, 2007
    #10
  11. Spiros Bousbouras

    santosh Guest

    dan wrote:

    > On Jul 30, 8:38 am, Spiros Bousbouras <> wrote:
    >> Every time I've seen an example of a variable argument list
    >> function its functionality was to print formatted output. Does
    >> anyone have examples where the function is not some variation
    >> of printf ?

    >
    > I got thinking the same thing recently. Can variable argument list
    > functions be used to make a function able to handle int, long, or
    > float, depending on what is passed? As a simple example, a MAX
    > function, as someone else mentioned, that could deal with different
    > number types.


    I'd rather implement this functionality through void * and an extra type
    parameter.

    > Is yes, would that be a good idea, or just better to write separate
    > functions?


    Separate functions might be the most flexible option.
     
    santosh, Jul 30, 2007
    #11
  12. Spiros Bousbouras

    Eric Sosman Guest

    dan wrote On 07/30/07 14:52,:
    > On Jul 30, 8:38 am, Spiros Bousbouras <> wrote:
    >
    >>Every time I've seen an example of a variable argument list
    >>function its functionality was to print formatted output. Does
    >>anyone have examples where the function is not some variation
    >>of printf ?

    >
    >
    > I got thinking the same thing recently. Can variable argument list
    > functions be used to make a function able to handle int, long, or
    > float, depending on what is passed? As a simple example, a MAX
    > function, as someone else mentioned, that could deal with different
    > number types.


    Yes, you could write such a function. But note that
    there is no "auto-detection" of the argument types; you must
    find some way to tell the function what kind(s) of arguments
    it has received. You could pass a first argument that's a
    code for the type of the others, for example.

    Other problems: The compiler doesn't know that you're
    supposed to pass three arguments, and will be happy to
    accept MAX(INTTYPE, 3, 4, 5) or MAX(DBLTYPE, 2.0) or
    even MAX(LONGTYPE). Equally, the compiler will be happy
    to accept MAX(LONGTYPE, 42, 42.0). Also, the function can
    only return values of one type; you could make a union of
    int/long/double, but there's no way for the the function to
    return a plain int for one call and a double for another.

    Variable argument lists do not equal "overloading."

    > Is yes, would that be a good idea, or just better to write separate
    > functions?


    Separate functions, by all means.

    --
     
    Eric Sosman, Jul 30, 2007
    #12
  13. Spiros Bousbouras wrote:
    >Every time I've seen an example of a variable argument list
    >function its functionality was to print formatted output. Does
    >anyone have examples where the function is not some variation
    >of printf ?


    A command interpreter for a simple test harness:

    command mandatory_1st_param optional_parameters...

    The parameters could be integers, a few predefined strings (RESET,
    CALIBRATE, etc.) translated to numeric codes, or arbitrary character
    strings to be passed to lower level logic (C0=24.53).

    First implementation begun parsing the parameters, classifying them by
    type and building the equivalent of a printf() format string to
    describe them before calling their handlers using varargs.

    Was short lived, changed the handlers to use a single parameter: a
    worst-case sized array of structures with a field for each possible
    parameter type and a special "end of list" struct.
    Was much easier to maintain than the varargs version.

    This is not too far removed from being "some variation of printf" ...

    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
     
    Roberto Waltman, Jul 30, 2007
    #13
  14. Richard Heathfield wrote:
    >
    > Kenneth Brody said:
    >
    > > Spiros Bousbouras wrote:
    > >>
    > >> Every time I've seen an example of a variable argument list
    > >> function its functionality was to print formatted output. Does
    > >> anyone have examples where the function is not some variation
    > >> of printf ?

    > >
    > > How about a version of strcat() that takes a list of strings, which
    > > could be called like this:
    > >
    > > StrCatList(MyBuffer,MyBufferLen,string1,string2,string3,NULL);
    > >
    > > Yes, one could use sprintf() for this, but strcat-like functionality
    > > is (most likely) more efficient.

    >
    > Since it's my day for being dense, I suppose I might as well attract
    > some flak for messing up the implementation:
    >
    > #include <stdarg.h>
    > #include <stddef.h>
    >
    > int catstrlist(char *buf, size_t len, ...)


    I was originally going to call mine "strcatlist()" but then recalled
    that the Standard reserves functions that start with "str" and a
    lowercase letter.

    [...]
    > memset(target, 0, sizeof target);


    Wouldn't "target[0] = '\0';" suffice?

    > rc = catstrlist(target,
    > sizeof target,
    > "Now", "Is", "The", "Hour", NULL);

    [...]

    --
    +-------------------------+--------------------+-----------------------+
    | Kenneth J. Brody | www.hvcomputer.com | #include |
    | kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
    +-------------------------+--------------------+-----------------------+
    Don't e-mail me at: <mailto:>
     
    Kenneth Brody, Jul 30, 2007
    #14
  15. "Spiros Bousbouras" <> wrote in message
    news:...
    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?
    >

    Go onto my website and download the file options.c.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
     
    Malcolm McLean, Jul 30, 2007
    #15
  16. Kenneth Brody said:

    > Richard Heathfield wrote:
    >>
    >> Kenneth Brody said:
    >>
    >> > Spiros Bousbouras wrote:
    >> >>
    >> >> Every time I've seen an example of a variable argument list
    >> >> function its functionality was to print formatted output. Does
    >> >> anyone have examples where the function is not some variation
    >> >> of printf ?
    >> >
    >> > How about a version of strcat() that takes a list of strings, which
    >> > could be called like this:
    >> >
    >> > StrCatList(MyBuffer,MyBufferLen,string1,string2,string3,NULL);
    >> >
    >> > Yes, one could use sprintf() for this, but strcat-like
    >> > functionality is (most likely) more efficient.

    >>
    >> Since it's my day for being dense, I suppose I might as well attract
    >> some flak for messing up the implementation:
    >>
    >> #include <stdarg.h>
    >> #include <stddef.h>
    >>
    >> int catstrlist(char *buf, size_t len, ...)

    >
    > I was originally going to call mine "strcatlist()" but then recalled
    > that the Standard reserves functions that start with "str" and a
    > lowercase letter.


    Yay me! I actually got something right. :)

    > [...]
    >> memset(target, 0, sizeof target);

    >
    > Wouldn't "target[0] = '\0';" suffice?


    Planning ahead. I was expecting problems, given the kind of day I'm
    having, and this was a "make sure we know the value of ***everything***
    before we actually make the call" thing.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jul 30, 2007
    #16
  17. Spiros Bousbouras

    Chris Torek Guest

    (I have not actually run this, but it looks correct aside from
    the bug I am about to note)

    In article <>
    Richard Heathfield <> wrote:
    >Since it's my day for being dense, I suppose I might as well attract
    >some flak for messing up the implementation:


    [much snippage]

    >int catstrlist(char *buf, size_t len, ...)


    [and]
    > rc = catstrlist(target,
    > sizeof target,
    > "Hello", "World", NULL);


    The macro NULL can be defined as plain 0 or as ((void *)0) (or in
    a number of other more-or-less equivalent ways).

    If it is defined as ((void *)0), the call above squeaks by on a
    technicality: (void *)0 and (char *)0 are necessarily "the same"
    in some fundamental sense, which probably extends to function
    calls.

    If NULL is defined as plain 0, however, the call can fail -- and
    does in fact fail, sometimes, on some implementations, such as
    those with 32-bit-int and 64-bit-pointer.

    The call *should* read, e.g.:

    rc = catstrlist(target,
    sizeof target,
    "Hello", "World", (char *)NULL);

    This is one of those rare cases where a cast is a good idea. It
    may be an even better idea to "wrap up" the cast into a #define:

    #define END_CATSTRLIST ((char *)NULL)
    ...
    result = catstrlist(target, sizeof target,
    "Hello", "World", END_CATSTRLIST);

    (On another note, this kind of variable-argument-list was in fact
    used in SunTools / SunWindows, back in its days. The variable
    arguments were tag-and-value pairs, and I think there was a defined
    tag meaning "end of tag/value pairs, and no value supplied this
    time".)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Jul 30, 2007
    #17
  18. Chris Torek said:

    > (I have not actually run this, but it looks correct aside from
    > the bug I am about to note)


    I told you it wasn't my day, didn't I?

    Thanks, Chris.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jul 30, 2007
    #18
  19. Groovy hepcat Spiros Bousbouras was jivin' in comp.lang.c on Tue, 31 Jul
    2007 2:38 am. It's a cool scene! Dig it.

    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    I have a function that merges (copies of) multiple linked lists. The
    prototype is this:

    struct dl_list_t *dl_MergeLists(size_t num, ...);

    The first argument represents the number of linked lists to merge.
    subsequent arguments must be of type struct dl_list_t *, and represent
    the linked lists to merge. The function makes copies of each of the
    linked list nodes, and stores them in a new linked list. It returns a
    struct dl_list_t * representing the new list.

    --
    Dig the sig!

    ----------- Peter 'Shaggy' Haywood ------------
    Ain't I'm a dawg!!
     
    Peter 'Shaggy' Haywood, Aug 3, 2007
    #19
  20. On Mon, 30 Jul 2007 16:38:44 -0000, Spiros Bousbouras
    <> wrote:

    > Every time I've seen an example of a variable argument list
    > function its functionality was to print formatted output. Does
    > anyone have examples where the function is not some variation
    > of printf ?


    There's an almost equal number of variations of scanf. <G>

    If I assume you meant to exclude both of those, in the Unix (POSIX)
    world, there's execl* as already noted, and also open() which uses it
    to make the third argument "optional" -- it is only used, and need
    only be provided, if (O_CREAT is specified and) the file is created.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Aug 26, 2007
    #20
    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. frank
    Replies:
    0
    Views:
    378
    frank
    Mar 7, 2005
  2. Ben Kial
    Replies:
    1
    Views:
    685
    Eric Enright
    Nov 15, 2004
  3. S?ren Gammelmark
    Replies:
    1
    Views:
    1,931
    Eric Sosman
    Jan 7, 2005
  4. Ross A. Finlayson
    Replies:
    19
    Views:
    625
    Keith Thompson
    Mar 10, 2005
  5. AikidoGuy
    Replies:
    11
    Views:
    577
    Seebs
    Nov 21, 2011
Loading...

Share This Page